svn commit: r193626 - stable/7/bin/ps

Brian Somers brian at FreeBSD.org
Sun Jun 7 08:11:26 UTC 2009


Author: brian
Date: Sun Jun  7 08:11:25 2009
New Revision: 193626
URL: http://svn.freebsd.org/changeset/base/193626

Log:
  MFC: r192239: Add a -d switch.

Modified:
  stable/7/bin/ps/   (props changed)
  stable/7/bin/ps/print.c
  stable/7/bin/ps/ps.1
  stable/7/bin/ps/ps.c
  stable/7/bin/ps/ps.h

Modified: stable/7/bin/ps/print.c
==============================================================================
--- stable/7/bin/ps/print.c	Sun Jun  7 07:45:25 2009	(r193625)
+++ stable/7/bin/ps/print.c	Sun Jun  7 08:11:25 2009	(r193626)
@@ -129,25 +129,33 @@ command(KINFO *k, VARENT *ve)
 	v = ve->var;
 	if (cflag) {
 		/* If it is the last field, then don't pad */
-		if (STAILQ_NEXT(ve, next_ve) == NULL)
+		if (STAILQ_NEXT(ve, next_ve) == NULL) {
+			if (k->ki_d.prefix)
+				(void)printf("%s", k->ki_d.prefix);
 			(void)printf("%s", k->ki_p->ki_comm);
-		else
+		} else
 			(void)printf("%-*s", v->width, k->ki_p->ki_comm);
 		return;
 	}
 	if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL)
 		errx(1, "malloc failed");
 	strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH);
-	if (k->ki_env) {
-		if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) == NULL)
-			errx(1, "malloc failed");
-		strvis(vis_env, k->ki_env, VIS_TAB | VIS_NL | VIS_NOSLASH);
-	} else
-		vis_env = NULL;
 
 	if (STAILQ_NEXT(ve, next_ve) == NULL) {
 		/* last field */
+
+		if (k->ki_env) {
+			if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1))
+			    == NULL)
+				errx(1, "malloc failed");
+			strvis(vis_env, k->ki_env,
+			    VIS_TAB | VIS_NL | VIS_NOSLASH);
+		} else
+			vis_env = NULL;
+
 		if (termwidth == UNLIMITED) {
+			if (k->ki_d.prefix)
+				(void)printf("%s", k->ki_d.prefix);
 			if (vis_env)
 				(void)printf("%s ", vis_env);
 			(void)printf("%s", vis_args);
@@ -155,6 +163,9 @@ command(KINFO *k, VARENT *ve)
 			left = termwidth - (totwidth - v->width);
 			if (left < 1) /* already wrapped, just use std width */
 				left = v->width;
+			if ((cp = k->ki_d.prefix) != NULL)
+				while (--left >= 0 && *cp)
+					(void)putchar(*cp++);
 			if ((cp = vis_env) != NULL) {
 				while (--left >= 0 && *cp)
 					(void)putchar(*cp++);
@@ -164,12 +175,12 @@ command(KINFO *k, VARENT *ve)
 			for (cp = vis_args; --left >= 0 && *cp != '\0';)
 				(void)putchar(*cp++);
 		}
+		if (vis_env != NULL)
+			free(vis_env);
 	} else
-		/* XXX env? */
+		/* ki_d.prefix & ki_env aren't shown for interim fields */
 		(void)printf("%-*.*s", v->width, v->width, vis_args);
 	free(vis_args);
-	if (vis_env != NULL)
-		free(vis_env);
 }
 
 void
@@ -178,9 +189,11 @@ ucomm(KINFO *k, VARENT *ve)
 	VAR *v;
 
 	v = ve->var;
-	if (STAILQ_NEXT(ve, next_ve) == NULL)	/* last field, don't pad */
+	if (STAILQ_NEXT(ve, next_ve) == NULL) {	/* last field, don't pad */
+		if (k->ki_d.prefix)
+			(void)printf("%s", k->ki_d.prefix);
 		(void)printf("%s", k->ki_p->ki_comm);
-	else
+	} else
 		(void)printf("%-*s", v->width, k->ki_p->ki_comm);
 }
 

Modified: stable/7/bin/ps/ps.1
==============================================================================
--- stable/7/bin/ps/ps.1	Sun Jun  7 07:45:25 2009	(r193625)
+++ stable/7/bin/ps/ps.1	Sun Jun  7 08:11:25 2009	(r193626)
@@ -29,7 +29,7 @@
 .\"     @(#)ps.1	8.3 (Berkeley) 4/18/94
 .\" $FreeBSD$
 .\"
-.Dd August 21, 2006
+.Dd May 16, 2009
 .Dt PS 1
 .Os
 .Sh NAME
@@ -37,7 +37,7 @@
 .Nd process status
 .Sh SYNOPSIS
 .Nm
-.Op Fl aCcefHhjlmrSTuvwXxZ
+.Op Fl aCcdefHhjlmrSTuvwXxZ
 .Op Fl O Ar fmt | Fl o Ar fmt
 .Op Fl G Ar gid Ns Op , Ns Ar gid Ns Ar ...
 .Op Fl M Ar core
@@ -122,6 +122,15 @@ CPU calculation that ignores
 .Dq resident
 time (this normally has
 no effect).
+.It Fl d
+Arrange processes into descendancy order and prefix each command with
+indentation text showing sibling and parent/child relationships.
+If either of the
+.Fl m
+and
+.Fl r
+options are also used, they control how sibling processes are sorted
+relative to eachother.
 .It Fl e
 Display the environment as well.
 .It Fl f

Modified: stable/7/bin/ps/ps.c
==============================================================================
--- stable/7/bin/ps/ps.c	Sun Jun  7 07:45:25 2009	(r193625)
+++ stable/7/bin/ps/ps.c	Sun Jun  7 08:11:25 2009	(r193626)
@@ -137,6 +137,7 @@ static int	 addelem_pid(struct listinfo 
 static int	 addelem_tty(struct listinfo *, const char *);
 static int	 addelem_uid(struct listinfo *, const char *);
 static void	 add_list(struct listinfo *, const char *);
+static void	 descendant_sort(KINFO *, int);
 static void	 dynsizevars(KINFO *);
 static void	*expand_list(struct listinfo *);
 static const char *
@@ -162,7 +163,7 @@ static char vfmt[] = "pid,state,time,sl,
 			"%cpu,%mem,command";
 static char Zfmt[] = "label";
 
-#define	PS_ARGS	"AaCce" OPT_LAZY_f "G:gHhjLlM:mN:O:o:p:rSTt:U:uvwXxZ"
+#define	PS_ARGS	"AaCcde" OPT_LAZY_f "G:gHhjLlM:mN:O:o:p:rSTt:U:uvwXxZ"
 
 int
 main(int argc, char *argv[])
@@ -176,7 +177,7 @@ main(int argc, char *argv[])
 	const char *nlistf, *memf;
 	char *cols;
 	int all, ch, elem, flag, _fmt, i, lineno;
-	int nentries, nkept, nselectors;
+	int descendancy, nentries, nkept, nselectors;
 	int prtheader, showthreads, wflag, what, xkeep, xkeep_implied;
 	char errbuf[_POSIX2_LINE_MAX];
 
@@ -200,7 +201,7 @@ main(int argc, char *argv[])
 	if (argc > 1)
 		argv[1] = kludge_oldps_options(PS_ARGS, argv[1], argv[2]);
 
-	all = _fmt = nselectors = optfatal = 0;
+	all = descendancy = _fmt = nselectors = optfatal = 0;
 	prtheader = showthreads = wflag = xkeep_implied = 0;
 	xkeep = -1;			/* Neither -x nor -X. */
 	init_list(&gidlist, addelem_gid, sizeof(gid_t), "group");
@@ -232,6 +233,9 @@ main(int argc, char *argv[])
 		case 'c':
 			cflag = 1;
 			break;
+		case 'd':
+			descendancy = 1;
+			break;
 		case 'e':			/* XXX set ufmt */
 			needenv = 1;
 			break;
@@ -574,6 +578,8 @@ main(int argc, char *argv[])
 		keepit:
 			next_KINFO = &kinfo[nkept];
 			next_KINFO->ki_p = kp;
+			next_KINFO->ki_d.level = 0;
+			next_KINFO->ki_d.prefix = NULL;
 			next_KINFO->ki_pcpu = getpcpu(next_KINFO);
 			if (sortby == SORTMEM)
 				next_KINFO->ki_memsize = kp->ki_tsize +
@@ -598,6 +604,13 @@ main(int argc, char *argv[])
 	 * sort proc list
 	 */
 	qsort(kinfo, nkept, sizeof(KINFO), pscomp);
+
+	/*
+	 * We want things in descendant order
+	 */
+	if (descendancy)
+		descendant_sort(kinfo, nkept);
+
 	/*
 	 * For each process, call each variable output function.
 	 */
@@ -621,6 +634,9 @@ main(int argc, char *argv[])
 	free_list(&sesslist);
 	free_list(&ttylist);
 	free_list(&uidlist);
+	for (i = 0; i < nkept; i++)
+		free(kinfo[i].ki_d.prefix);
+	free(kinfo);
 
 	exit(eval);
 }
@@ -889,6 +905,116 @@ add_list(struct listinfo *inf, const cha
 	}
 }
 
+static void
+descendant_sort(KINFO *ki, int items)
+{
+	int dst, lvl, maxlvl, n, ndst, nsrc, siblings, src;
+	unsigned char *path;
+	KINFO kn;
+
+	/*
+	 * First, sort the entries by descendancy, tracking the descendancy
+	 * depth in the ki_d.level field.
+	 */
+	src = 0;
+	maxlvl = 0;
+	while (src < items) {
+		if (ki[src].ki_d.level) {
+			src++;
+			continue;
+		}
+		for (nsrc = 1; src + nsrc < items; nsrc++)
+			if (!ki[src + nsrc].ki_d.level)
+				break;
+
+		for (dst = 0; dst < items; dst++) {
+			if (ki[dst].ki_p->ki_pid == ki[src].ki_p->ki_pid)
+				continue;
+			if (ki[dst].ki_p->ki_pid == ki[src].ki_p->ki_ppid)
+				break;
+		}
+
+		if (dst == items) {
+			src += nsrc;
+			continue;
+		}
+
+		for (ndst = 1; dst + ndst < items; ndst++)
+			if (ki[dst + ndst].ki_d.level <= ki[dst].ki_d.level)
+				break;
+
+		for (n = src; n < src + nsrc; n++) {
+			ki[n].ki_d.level += ki[dst].ki_d.level + 1;
+			if (maxlvl < ki[n].ki_d.level)
+				maxlvl = ki[n].ki_d.level;
+		}
+
+		while (nsrc) {
+			if (src < dst) {
+				kn = ki[src];
+				memmove(ki + src, ki + src + 1,
+				    (dst - src + ndst - 1) * sizeof *ki);
+				ki[dst + ndst - 1] = kn;
+				nsrc--;
+				dst--;
+				ndst++;
+			} else if (src != dst + ndst) {
+				kn = ki[src];
+				memmove(ki + dst + ndst + 1, ki + dst + ndst,
+				    (src - dst - ndst) * sizeof *ki);
+				ki[dst + ndst] = kn;
+				ndst++;
+				nsrc--;
+				src++;
+			} else {
+				ndst += nsrc;
+				src += nsrc;
+				nsrc = 0;
+			}
+		}
+	}
+
+	/*
+	 * Now populate ki_d.prefix (instead of ki_d.level) with the command
+	 * prefix used to show descendancies.
+	 */
+	path = malloc((maxlvl + 7) / 8);
+	memset(path, '\0', (maxlvl + 7) / 8);
+	for (src = 0; src < items; src++) {
+		if ((lvl = ki[src].ki_d.level) == 0) {
+			ki[src].ki_d.prefix = NULL;
+			continue;
+		}
+		if ((ki[src].ki_d.prefix = malloc(lvl * 2 + 1)) == NULL)
+			errx(1, "malloc failed");
+		for (n = 0; n < lvl - 2; n++) {
+			ki[src].ki_d.prefix[n * 2] =
+			    path[n / 8] & 1 << (n % 8) ? '|' : ' ';
+			ki[src].ki_d.prefix[n * 2 + 1] = ' ';
+				
+		}
+		if (n == lvl - 2) {
+			/* Have I any more siblings? */
+			for (siblings = 0, dst = src + 1; dst < items; dst++) {
+				if (ki[dst].ki_d.level > lvl)
+					continue;
+				if (ki[dst].ki_d.level == lvl)
+					siblings = 1;
+				break;
+			}
+			if (siblings)
+				path[n / 8] |= 1 << (n % 8);
+			else
+				path[n / 8] &= ~(1 << (n % 8));
+			ki[src].ki_d.prefix[n * 2] = siblings ? '|' : '`';
+			ki[src].ki_d.prefix[n * 2 + 1] = '-';
+			n++;
+		}
+		strcpy(ki[src].ki_d.prefix + n * 2, "- ");
+	}
+	free(path);
+}
+
 static void *
 expand_list(struct listinfo *inf)
 {

Modified: stable/7/bin/ps/ps.h
==============================================================================
--- stable/7/bin/ps/ps.h	Sun Jun  7 07:45:25 2009	(r193625)
+++ stable/7/bin/ps/ps.h	Sun Jun  7 08:11:25 2009	(r193626)
@@ -42,6 +42,10 @@ typedef struct kinfo {
 	int ki_valid;		/* 1 => uarea stuff valid */
 	double	 ki_pcpu;	/* calculated in main() */
 	segsz_t	 ki_memsize;	/* calculated in main() */
+	union {
+		int level;	/* used in decendant_sort() */
+		char *prefix;	/* calculated in decendant_sort() */
+	} ki_d;
 } KINFO;
 
 /* Variables. */


More information about the svn-src-stable-7 mailing list