Module Name:    src
Committed By:   christos
Date:           Fri Dec  2 21:59:03 UTC 2016

Modified Files:
        src/bin/ps: extern.h print.c ps.1 ps.c ps.h

Log Message:
provide a tree like display with -d, from FreeBSD


To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/bin/ps/extern.h
cvs rdiff -u -r1.125 -r1.126 src/bin/ps/print.c
cvs rdiff -u -r1.105 -r1.106 src/bin/ps/ps.1
cvs rdiff -u -r1.86 -r1.87 src/bin/ps/ps.c
cvs rdiff -u -r1.28 -r1.29 src/bin/ps/ps.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/bin/ps/extern.h
diff -u src/bin/ps/extern.h:1.37 src/bin/ps/extern.h:1.38
--- src/bin/ps/extern.h:1.37	Mon Nov 28 03:21:10 2016
+++ src/bin/ps/extern.h	Fri Dec  2 16:59:03 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: extern.h,v 1.37 2016/11/28 08:21:10 rin Exp $	*/
+/*	$NetBSD: extern.h,v 1.38 2016/12/02 21:59:03 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993, 1994
@@ -46,54 +46,54 @@ extern VAR var[];
 extern VARLIST displaylist;
 extern VARLIST sortlist;
 
-void	 command(void *, VARENT *, enum mode);
-void	 cpuid(void *, VARENT *, enum mode);
-void	 cputime(void *, VARENT *, enum mode);
+void	 command(struct pinfo *, VARENT *, enum mode);
+void	 cpuid(struct pinfo *, VARENT *, enum mode);
+void	 cputime(struct pinfo *, VARENT *, enum mode);
 void	 donlist(void);
 void	 donlist_sysctl(void);
 void	 fmt_puts(char *, int *);
 void	 fmt_putc(int, int *);
-void	 elapsed(void *, VARENT *, enum mode);
+void	 elapsed(struct pinfo *, VARENT *, enum mode);
 double	 getpcpu(const struct kinfo_proc2 *);
 double	 getpmem(const struct kinfo_proc2 *);
-void	 gname(void *, VARENT *, enum mode);
-void	 groups(void *, VARENT *, enum mode);
-void	 groupnames(void *, VARENT *, enum mode);
-void	 lcputime(void *, VARENT *, enum mode);
-void	 logname(void *, VARENT *, enum mode);
-void	 longtname(void *, VARENT *, enum mode);
-void	 lname(void *, VARENT *, enum mode);
-void	 lstarted(void *, VARENT *, enum mode);
-void	 lstate(void *, VARENT *, enum mode);
-void	 maxrss(void *, VARENT *, enum mode);
+void	 gname(struct pinfo *, VARENT *, enum mode);
+void	 groups(struct pinfo *, VARENT *, enum mode);
+void	 groupnames(struct pinfo *, VARENT *, enum mode);
+void	 lcputime(struct pinfo *, VARENT *, enum mode);
+void	 logname(struct pinfo *, VARENT *, enum mode);
+void	 longtname(struct pinfo *, VARENT *, enum mode);
+void	 lname(struct pinfo *, VARENT *, enum mode);
+void	 lstarted(struct pinfo *, VARENT *, enum mode);
+void	 lstate(struct pinfo *, VARENT *, enum mode);
+void	 maxrss(struct pinfo *, VARENT *, enum mode);
 void	 nlisterr(struct nlist *);
-void	 p_rssize(void *, VARENT *, enum mode);
-void	 pagein(void *, VARENT *, enum mode);
+void	 p_rssize(struct pinfo *, VARENT *, enum mode);
+void	 pagein(struct pinfo *, VARENT *, enum mode);
 void	 parsefmt(const char *);
 void	 parsefmt_insert(const char *, VARENT **);
 void	 parsesort(const char *);
 VARENT * varlist_find(VARLIST *, const char *);
-void	 emul(void *, VARENT *, enum mode);
-void	 pcpu(void *, VARENT *, enum mode);
-void	 pmem(void *, VARENT *, enum mode);
-void	 pnice(void *, VARENT *, enum mode);
-void	 pri(void *, VARENT *, enum mode);
+void	 emul(struct pinfo *, VARENT *, enum mode);
+void	 pcpu(struct pinfo *, VARENT *, enum mode);
+void	 pmem(struct pinfo *, VARENT *, enum mode);
+void	 pnice(struct pinfo *, VARENT *, enum mode);
+void	 pri(struct pinfo *, VARENT *, enum mode);
 void	 printheader(void);
-void	 putimeval(void *, VARENT *, enum mode);
-void	 pvar(void *, VARENT *, enum mode);
-void	 rgname(void *, VARENT *, enum mode);
-void	 rssize(void *, VARENT *, enum mode);
-void	 runame(void *, VARENT *, enum mode);
+void	 putimeval(struct pinfo *, VARENT *, enum mode);
+void	 pvar(struct pinfo *, VARENT *, enum mode);
+void	 rgname(struct pinfo *, VARENT *, enum mode);
+void	 rssize(struct pinfo *, VARENT *, enum mode);
+void	 runame(struct pinfo *, VARENT *, enum mode);
 void	 showkey(void);
-void	 started(void *, VARENT *, enum mode);
-void	 state(void *, VARENT *, enum mode);
-void	 svgname(void *, VARENT *, enum mode);
-void	 svuname(void *, VARENT *, enum mode);
-void	 tdev(void *, VARENT *, enum mode);
-void	 tname(void *, VARENT *, enum mode);
-void	 tsize(void *, VARENT *, enum mode);
-void	 ucomm(void *, VARENT *, enum mode);
-void	 uname(void *, VARENT *, enum mode);
-void	 uvar(void *, VARENT *, enum mode);
-void	 vsize(void *, VARENT *, enum mode);
-void	 wchan(void *, VARENT *, enum mode);
+void	 started(struct pinfo *, VARENT *, enum mode);
+void	 state(struct pinfo *, VARENT *, enum mode);
+void	 svgname(struct pinfo *, VARENT *, enum mode);
+void	 svuname(struct pinfo *, VARENT *, enum mode);
+void	 tdev(struct pinfo *, VARENT *, enum mode);
+void	 tname(struct pinfo *, VARENT *, enum mode);
+void	 tsize(struct pinfo *, VARENT *, enum mode);
+void	 ucomm(struct pinfo *, VARENT *, enum mode);
+void	 uname(struct pinfo *, VARENT *, enum mode);
+void	 uvar(struct pinfo *, VARENT *, enum mode);
+void	 vsize(struct pinfo *, VARENT *, enum mode);
+void	 wchan(struct pinfo *, VARENT *, enum mode);

Index: src/bin/ps/print.c
diff -u src/bin/ps/print.c:1.125 src/bin/ps/print.c:1.126
--- src/bin/ps/print.c:1.125	Mon Nov 28 03:21:10 2016
+++ src/bin/ps/print.c	Fri Dec  2 16:59:03 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: print.c,v 1.125 2016/11/28 08:21:10 rin Exp $	*/
+/*	$NetBSD: print.c,v 1.126 2016/12/02 21:59:03 christos Exp $	*/
 
 /*
  * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
 #if 0
 static char sccsid[] = "@(#)print.c	8.6 (Berkeley) 4/16/94";
 #else
-__RCSID("$NetBSD: print.c,v 1.125 2016/11/28 08:21:10 rin Exp $");
+__RCSID("$NetBSD: print.c,v 1.126 2016/12/02 21:59:03 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -278,9 +278,9 @@ strprintorsetwidth(VAR *v, const char *s
 }
 
 void
-command(void *arg, VARENT *ve, enum mode mode)
+command(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *ki;
+	struct kinfo_proc2 *ki = pi->ki;
 	VAR *v;
 	int left;
 	char **argv, **p, *name;
@@ -288,7 +288,6 @@ command(void *arg, VARENT *ve, enum mode
 	if (mode == WIDTHMODE)
 		return;
 
-	ki = arg;
 	v = ve->var;
 	if (SIMPLEQ_NEXT(ve, next) != NULL || termwidth != UNLIMITED) {
 		if (SIMPLEQ_NEXT(ve, next) == NULL) {
@@ -310,6 +309,8 @@ command(void *arg, VARENT *ve, enum mode
 		}
 	}
 	if (needcomm) {
+		if (pi->prefix)
+			(void)fmt_puts(pi->prefix, &left);
 		name = ki->p_comm;
 		if (!commandonly) {
 			argv = kvm_getargv2(kd, ki, termwidth);
@@ -359,9 +360,9 @@ command(void *arg, VARENT *ve, enum mode
 }
 
 void
-groups(void *arg, VARENT *ve, enum mode mode)
+groups(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *ki;
+	struct kinfo_proc2 *ki = pi->ki;
 	VAR *v;
 	int left, i;
 	char buf[16], *p;
@@ -369,7 +370,6 @@ groups(void *arg, VARENT *ve, enum mode 
 	if (mode == WIDTHMODE)
 		return;
 
-	ki = arg;
 	v = ve->var;
 	if (SIMPLEQ_NEXT(ve, next) != NULL || termwidth != UNLIMITED) {
 		if (SIMPLEQ_NEXT(ve, next) == NULL) {
@@ -397,9 +397,9 @@ groups(void *arg, VARENT *ve, enum mode 
 }
 
 void
-groupnames(void *arg, VARENT *ve, enum mode mode)
+groupnames(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *ki;
+	struct kinfo_proc2 *ki = pi->ki;
 	VAR *v;
 	int left, i;
 	const char *p;
@@ -407,7 +407,6 @@ groupnames(void *arg, VARENT *ve, enum m
 	if (mode == WIDTHMODE)
 		return;
 
-	ki = arg;
 	v = ve->var;
 	if (SIMPLEQ_NEXT(ve, next) != NULL || termwidth != UNLIMITED) {
 		if (SIMPLEQ_NEXT(ve, next) == NULL) {
@@ -434,48 +433,49 @@ groupnames(void *arg, VARENT *ve, enum m
 }
 
 void
-ucomm(void *arg, VARENT *ve, enum mode mode)
+ucomm(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
+	char buf[MAXPATHLEN], *p;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
-	strprintorsetwidth(v, k->p_comm, mode);
+	if (pi->prefix)
+		snprintf(p = buf, sizeof(buf), "%s%s", pi->prefix, k->p_comm);
+	else
+		p = k->p_comm;
+	strprintorsetwidth(v, p, mode);
 }
 
 void
-emul(void *arg, VARENT *ve, enum mode mode)
+emul(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	strprintorsetwidth(v, k->p_ename, mode);
 }
 
 void
-logname(void *arg, VARENT *ve, enum mode mode)
+logname(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	strprintorsetwidth(v, k->p_login, mode);
 }
 
 void
-state(void *arg, VARENT *ve, enum mode mode)
+state(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	int flag, is_zombie;
 	char *cp;
 	VAR *v;
 	char buf[16];
 
-	k = arg;
 	is_zombie = 0;
 	v = ve->var;
 	flag = k->p_flag;
@@ -551,15 +551,14 @@ state(void *arg, VARENT *ve, enum mode m
 }
 
 void
-lstate(void *arg, VARENT *ve, enum mode mode)
+lstate(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_lwp *k;
+	struct kinfo_lwp *k = pi->li;
 	int flag;
 	char *cp;
 	VAR *v;
 	char buf[16];
 
-	k = arg;
 	v = ve->var;
 	flag = k->l_flag;
 	cp = buf;
@@ -610,102 +609,93 @@ lstate(void *arg, VARENT *ve, enum mode 
 }
 
 void
-pnice(void *arg, VARENT *ve, enum mode mode)
+pnice(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	intprintorsetwidth(v, k->p_nice - NZERO, mode);
 }
 
 void
-pri(void *arg, VARENT *ve, enum mode mode)
+pri(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_lwp *l;
+	struct kinfo_lwp *l = pi->li;
 	VAR *v;
 
-	l = arg;
 	v = ve->var;
 	intprintorsetwidth(v, l->l_priority, mode);
 }
 
 void
-uname(void *arg, VARENT *ve, enum mode mode)
+uname(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	strprintorsetwidth(v, user_from_uid(k->p_uid, 0), mode);
 }
 
 void
-runame(void *arg, VARENT *ve, enum mode mode)
+runame(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	strprintorsetwidth(v, user_from_uid(k->p_ruid, 0), mode);
 }
 
 void
-svuname(void *arg, VARENT *ve, enum mode mode)
+svuname(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	strprintorsetwidth(v, user_from_uid(k->p_svuid, 0), mode);
 }
 
 void
-gname(void *arg, VARENT *ve, enum mode mode)
+gname(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	strprintorsetwidth(v, group_from_gid(k->p_gid, 0), mode);
 }
 
 void
-rgname(void *arg, VARENT *ve, enum mode mode)
+rgname(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	strprintorsetwidth(v, group_from_gid(k->p_rgid, 0), mode);
 }
 
 void
-svgname(void *arg, VARENT *ve, enum mode mode)
+svgname(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	strprintorsetwidth(v, group_from_gid(k->p_svgid, 0), mode);
 }
 
 void
-tdev(void *arg, VARENT *ve, enum mode mode)
+tdev(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 	dev_t dev;
 	char buff[16];
 
-	k = arg;
 	v = ve->var;
 	dev = k->p_tdev;
 	if (dev == NODEV) {
@@ -722,15 +712,14 @@ tdev(void *arg, VARENT *ve, enum mode mo
 }
 
 void
-tname(void *arg, VARENT *ve, enum mode mode)
+tname(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 	dev_t dev;
 	const char *ttname;
 	int noctty;
 
-	k = arg;
 	v = ve->var;
 	dev = k->p_tdev;
 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) {
@@ -757,14 +746,13 @@ tname(void *arg, VARENT *ve, enum mode m
 }
 
 void
-longtname(void *arg, VARENT *ve, enum mode mode)
+longtname(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 	dev_t dev;
 	const char *ttname;
 
-	k = arg;
 	v = ve->var;
 	dev = k->p_tdev;
 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) {
@@ -779,15 +767,14 @@ longtname(void *arg, VARENT *ve, enum mo
 }
 
 void
-started(void *arg, VARENT *ve, enum mode mode)
+started(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 	time_t startt;
 	struct tm *tp;
 	char buf[100], *cp;
 
-	k = arg;
 	v = ve->var;
 	if (!k->p_uvalid) {
 		if (mode == PRINTMODE)
@@ -815,14 +802,13 @@ started(void *arg, VARENT *ve, enum mode
 }
 
 void
-lstarted(void *arg, VARENT *ve, enum mode mode)
+lstarted(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 	time_t startt;
 	char buf[100];
 
-	k = arg;
 	v = ve->var;
 	if (!k->p_uvalid) {
 		/*
@@ -844,14 +830,13 @@ lstarted(void *arg, VARENT *ve, enum mod
 }
 
 void
-elapsed(void *arg, VARENT *ve, enum mode mode)
+elapsed(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 	int32_t origseconds, secs, mins, hours, days;
 	int fmtlen, printed_something;
 
-	k = arg;
 	v = ve->var;
 	if (k->p_uvalid == 0) {
 		origseconds = 0;
@@ -938,13 +923,12 @@ elapsed(void *arg, VARENT *ve, enum mode
 }
 
 void
-wchan(void *arg, VARENT *ve, enum mode mode)
+wchan(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_lwp *l;
+	struct kinfo_lwp *l = pi->li;
 	VAR *v;
 	char *buf;
 
-	l = arg;
 	v = ve->var;
 	if (l->l_wchan) {
 		if (l->l_wmesg[0]) {
@@ -968,46 +952,42 @@ wchan(void *arg, VARENT *ve, enum mode m
 #define	pgtok(a)        (((a)*(size_t)getpagesize())/1024)
 
 void
-vsize(void *arg, VARENT *ve, enum mode mode)
+vsize(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	intprintorsetwidth(v, pgtok(k->p_vm_msize), mode);
 }
 
 void
-rssize(void *arg, VARENT *ve, enum mode mode)
+rssize(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	/* XXX don't have info about shared */
 	intprintorsetwidth(v, pgtok(k->p_vm_rssize), mode);
 }
 
 void
-p_rssize(void *arg, VARENT *ve, enum mode mode)	/* doesn't account for text */
+p_rssize(struct pinfo *pi, VARENT *ve, enum mode mode)	/* doesn't account for text */
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	intprintorsetwidth(v, pgtok(k->p_vm_rssize), mode);
 }
 
 void
-cpuid(void *arg, VARENT *ve, enum mode mode)
+cpuid(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_lwp *l;
+	struct kinfo_lwp *l = pi->li;
 	VAR *v;
 
-	l = arg;
 	v = ve->var;
 	intprintorsetwidth(v, l->l_cpuid, mode);
 }
@@ -1049,14 +1029,13 @@ cputime1(int32_t secs, int32_t psecs, VA
 }
 
 void
-cputime(void *arg, VARENT *ve, enum mode mode)
+cputime(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 	int32_t secs;
 	int32_t psecs;	/* "parts" of a second. first micro, then centi */
 
-	k = arg;
 	v = ve->var;
 
 	/*
@@ -1075,14 +1054,13 @@ cputime(void *arg, VARENT *ve, enum mode
 }
 
 void
-lcputime(void *arg, VARENT *ve, enum mode mode)
+lcputime(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_lwp *l;
+	struct kinfo_lwp *l = pi->li;
 	VAR *v;
 	int32_t secs;
 	int32_t psecs;	/* "parts" of a second. first micro, then centi */
 
-	l = arg;
 	v = ve->var;
 
 	secs = l->l_rtime_sec;
@@ -1092,13 +1070,13 @@ lcputime(void *arg, VARENT *ve, enum mod
 }
 
 void
-pcpu(void *arg, VARENT *ve, enum mode mode)
+pcpu(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
 	VAR *v;
 	double dbl;
 
 	v = ve->var;
-	dbl = ((struct pinfo *)arg)->pcpu;
+	dbl = pi->pcpu;
 	doubleprintorsetwidth(v, dbl, (dbl >= 99.95) ? 0 : 1, mode);
 }
 
@@ -1119,29 +1097,27 @@ getpmem(const struct kinfo_proc2 *k)
 }
 
 void
-pmem(void *arg, VARENT *ve, enum mode mode)
+pmem(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	doubleprintorsetwidth(v, getpmem(k), 1, mode);
 }
 
 void
-pagein(void *arg, VARENT *ve, enum mode mode)
+pagein(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	intprintorsetwidth(v, k->p_uvalid ? k->p_uru_majflt : 0, mode);
 }
 
 void
-maxrss(void *arg, VARENT *ve, enum mode mode)
+maxrss(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
 	VAR *v;
 
@@ -1152,12 +1128,11 @@ maxrss(void *arg, VARENT *ve, enum mode 
 }
 
 void
-tsize(void *arg, VARENT *ve, enum mode mode)
+tsize(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_proc2 *k;
+	struct kinfo_proc2 *k = pi->ki;
 	VAR *v;
 
-	k = arg;
 	v = ve->var;
 	intprintorsetwidth(v, pgtok(k->p_vm_tsize), mode);
 }
@@ -1365,27 +1340,28 @@ printval(void *bp, VAR *v, enum mode mod
 }
 
 void
-pvar(void *arg, VARENT *ve, enum mode mode)
+pvar(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
+	struct kinfo_proc2 *ki = pi->ki;
 	VAR *v;
 
 	v = ve->var;
-	if (v->flag & UAREA && !((struct kinfo_proc2 *)arg)->p_uvalid) {
+	if (v->flag & UAREA && !ki->p_uvalid) {
 		if (mode == PRINTMODE)
 			(void)printf("%*s", v->width, "-");
 		return;
 	}
 
-	(void)printval((char *)arg + v->off, v, mode);
+	(void)printval((char *)ki + v->off, v, mode);
 }
 
 void
-putimeval(void *arg, VARENT *ve, enum mode mode)
+putimeval(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
 	VAR *v = ve->var;
-	struct kinfo_proc2 *k = arg;
-	ulong secs = *(uint32_t *)((char *)arg + v->off);
-	ulong usec = *(uint32_t *)((char *)arg + v->off + sizeof (uint32_t));
+	struct kinfo_proc2 *k = pi->ki;
+	ulong secs = *(uint32_t *)((char *)k + v->off);
+	ulong usec = *(uint32_t *)((char *)k + v->off + sizeof (uint32_t));
 	int fmtlen;
 
 	if (!k->p_uvalid) {
@@ -1432,12 +1408,11 @@ putimeval(void *arg, VARENT *ve, enum mo
 }
 
 void
-lname(void *arg, VARENT *ve, enum mode mode)
+lname(struct pinfo *pi, VARENT *ve, enum mode mode)
 {
-	struct kinfo_lwp *l;
+	struct kinfo_lwp *l = pi->li;
 	VAR *v;
 
-	l = arg;
 	v = ve->var;
 	if (l->l_name[0] != '\0') {
 		strprintorsetwidth(v, l->l_name, mode);

Index: src/bin/ps/ps.1
diff -u src/bin/ps/ps.1:1.105 src/bin/ps/ps.1:1.106
--- src/bin/ps/ps.1:1.105	Wed Aug 10 18:00:56 2016
+++ src/bin/ps/ps.1	Fri Dec  2 16:59:03 2016
@@ -1,4 +1,4 @@
-.\"	$NetBSD: ps.1,v 1.105 2016/08/10 22:00:56 sevan Exp $
+.\"	$NetBSD: ps.1,v 1.106 2016/12/02 21:59:03 christos Exp $
 .\"
 .\" Copyright (c) 1980, 1990, 1991, 1993, 1994
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)ps.1	8.3 (Berkeley) 4/18/94
 .\"
-.Dd August 10, 2016
+.Dd December 2, 2016
 .Dt PS 1
 .Os
 .Sh NAME
@@ -37,7 +37,7 @@
 .Nd process status
 .Sh SYNOPSIS
 .Nm
-.Op Fl AaCcehjlmrSsTuvwx
+.Op Fl AaCcdehjlmrSsTuvwx
 .Op Fl k Ar key
 .Op Fl M Ar core
 .Op Fl N Ar system
@@ -99,6 +99,15 @@ This may be somewhat confusing; for exam
 .Xr sh 1
 scripts will show as
 .Dq sh .
+.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 each other.
 .It Fl e
 Display the environment as well.
 The environment for other

Index: src/bin/ps/ps.c
diff -u src/bin/ps/ps.c:1.86 src/bin/ps/ps.c:1.87
--- src/bin/ps/ps.c:1.86	Mon Nov 28 03:21:10 2016
+++ src/bin/ps/ps.c	Fri Dec  2 16:59:03 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ps.c,v 1.86 2016/11/28 08:21:10 rin Exp $	*/
+/*	$NetBSD: ps.c,v 1.87 2016/12/02 21:59:03 christos Exp $	*/
 
 /*
  * Copyright (c) 2000-2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@ __COPYRIGHT("@(#) Copyright (c) 1990, 19
 #if 0
 static char sccsid[] = "@(#)ps.c	8.4 (Berkeley) 4/2/94";
 #else
-__RCSID("$NetBSD: ps.c,v 1.86 2016/11/28 08:21:10 rin Exp $");
+__RCSID("$NetBSD: ps.c,v 1.87 2016/12/02 21:59:03 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -104,7 +104,7 @@ __RCSID("$NetBSD: ps.c,v 1.86 2016/11/28
  * ARGOPTS must contain all option characters that take arguments
  * (except for 't'!) - it is used in kludge_oldps_options()
  */
-#define	GETOPTSTR	"aAcCeghjk:LlM:mN:O:o:p:rSsTt:U:uvW:wx"
+#define	GETOPTSTR	"aAcCdeghjk:LlM:mN:O:o:p:rSsTt:U:uvW:wx"
 #define	ARGOPTS		"kMNOopUW"
 
 struct varlist displaylist = SIMPLEQ_HEAD_INITIALIZER(displaylist);
@@ -130,6 +130,7 @@ static int	 pscomp(const void *, const v
 static void	 scanvars(void);
 __dead static void	 usage(void);
 static int	 parsenum(const char *, const char *);
+static void	 descendant_sort(struct pinfo *, int);
 
 char dfmt[] = "pid tt state time command";
 char jfmt[] = "user pid ppid pgid sess jobc state tt time command";
@@ -203,7 +204,7 @@ main(int argc, char *argv[])
 	struct varent *vent;
 	struct winsize ws;
 	struct kinfo_lwp *kl, *l;
-	int ch, i, j, fmt, lineno, nentries, nlwps;
+	int ch, i, j, fmt, lineno, descendancy, nentries, nlwps;
 	long long flag;
 	int calc_pcpu, prtheader, wflag, what, xflg, rawcpu, showlwps;
 	char *nlistf, *memf, *swapf, errbuf[_POSIX2_LINE_MAX];
@@ -223,7 +224,7 @@ main(int argc, char *argv[])
 	if (argc > 1)
 		argv[1] = kludge_oldps_options(argv[1]);
 
-	fmt = prtheader = wflag = xflg = showlwps = 0;
+	descendancy = fmt = prtheader = wflag = xflg = showlwps = 0;
 	what = KERN_PROC_UID;
 	flag = myuid = getuid();
 	memf = nlistf = swapf = NULL;
@@ -241,6 +242,9 @@ main(int argc, char *argv[])
 		case 'c':
 			commandonly = 1;
 			break;
+		case 'd':
+			descendancy = 1;
+			break;
 		case 'e':			/* XXX set ufmt */
 			needenv = 1;
 			break;
@@ -432,6 +436,13 @@ main(int argc, char *argv[])
 	 * sort proc list
 	 */
 	qsort(pinfo, nentries, sizeof(struct pinfo), pscomp);
+
+	/*
+	 * We want things in descendant order
+	 */
+	if (descendancy)
+		descendant_sort(pinfo, nentries);
+
 	/*
 	 * For each proc, call each variable output function in
 	 * "setwidth" mode to determine the widest element of
@@ -589,9 +600,9 @@ setpinfo(struct kinfo_proc2 *ki, int nen
 	struct pinfo *pi;
 	int i;
 
-	pi = malloc(nentries * sizeof(struct pinfo));
+	pi = calloc(nentries, sizeof(*pi));
 	if (pi == NULL)
-		err(1, "malloc");
+		err(1, "calloc");
 
 	if (calc_pcpu && !nlistread)
 		donlist();
@@ -814,12 +825,122 @@ parsenum(const char *str, const char *ms
 }
 
 static void
+descendant_sort(struct pinfo *ki, int items)
+{
+	int dst, lvl, maxlvl, n, ndst, nsrc, siblings, src;
+	unsigned char *path;
+	struct pinfo kn;
+
+	/*
+	 * First, sort the entries by descendancy, tracking the descendancy
+	 * depth in the level field.
+	 */
+	src = 0;
+	maxlvl = 0;
+	while (src < items) {
+		if (ki[src].level) {
+			src++;
+			continue;
+		}
+		for (nsrc = 1; src + nsrc < items; nsrc++)
+			if (!ki[src + nsrc].level)
+				break;
+
+		for (dst = 0; dst < items; dst++) {
+			if (ki[dst].ki->p_pid == ki[src].ki->p_pid)
+				continue;
+			if (ki[dst].ki->p_pid == ki[src].ki->p_ppid)
+				break;
+		}
+
+		if (dst == items) {
+			src += nsrc;
+			continue;
+		}
+
+		for (ndst = 1; dst + ndst < items; ndst++)
+			if (ki[dst + ndst].level <= ki[dst].level)
+				break;
+
+		for (n = src; n < src + nsrc; n++) {
+			ki[n].level += ki[dst].level + 1;
+			if (maxlvl < ki[n].level)
+				maxlvl = ki[n].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 prefix (instead of 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].level) == 0) {
+			ki[src].prefix = NULL;
+			continue;
+		}
+		if ((ki[src].prefix = malloc(lvl * 2 + 1)) == NULL)
+			errx(1, "malloc failed");
+		for (n = 0; n < lvl - 2; n++) {
+			ki[src].prefix[n * 2] =
+			    path[n / 8] & 1 << (n % 8) ? '|' : ' ';
+			ki[src].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].level > lvl)
+					continue;
+				if (ki[dst].level == lvl)
+					siblings = 1;
+				break;
+			}
+			if (siblings)
+				path[n / 8] |= 1 << (n % 8);
+			else
+				path[n / 8] &= ~(1 << (n % 8));
+			ki[src].prefix[n * 2] = siblings ? '|' : '`';
+			ki[src].prefix[n * 2 + 1] = '-';
+			n++;
+		}
+		strcpy(ki[src].prefix + n * 2, "- ");
+	}
+	free(path);
+}
+
+static void
 usage(void)
 {
 
 	(void)fprintf(stderr,
 	    "usage:\t%s\n\t   %s\n\t%s\n",
-	    "ps [-AaCcehjlmrSsTuvwx] [-k key] [-M core] [-N system] [-O fmt]",
+	    "ps [-AaCcdehjlmrSsTuvwx] [-k key] [-M core] [-N system] [-O fmt]",
 	    "[-o fmt] [-p pid] [-t tty] [-U user] [-W swap]",
 	    "ps -L");
 	exit(1);

Index: src/bin/ps/ps.h
diff -u src/bin/ps/ps.h:1.28 src/bin/ps/ps.h:1.29
--- src/bin/ps/ps.h:1.28	Mon Nov 28 03:21:10 2016
+++ src/bin/ps/ps.h	Fri Dec  2 16:59:03 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ps.h,v 1.28 2016/11/28 08:21:10 rin Exp $	*/
+/*	$NetBSD: ps.h,v 1.29 2016/12/02 21:59:03 christos Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993
@@ -55,6 +55,14 @@ typedef struct varent {
 	struct var *var;
 } VARENT;
 
+struct pinfo {
+	struct kinfo_proc2 *ki;
+	struct kinfo_lwp *li;
+	char *prefix;
+	int level;
+	double pcpu;
+};
+
 typedef struct var {
 	const char *name;	/* name(s) of variable */
 	const char *header;	/* header, possibly changed from default */
@@ -67,7 +75,7 @@ typedef struct var {
 #define	ALIAS	0x40		/* entry is alias for 'header' */
 	u_int	flag;
 				/* output routine */
-	void	(*oproc)(void *, struct varent *, enum mode);
+	void	(*oproc)(struct pinfo *pi, struct varent *, enum mode);
 	/*
 	 * The following (optional) elements are hooks for passing information
 	 * to the generic output routine: pvar (that which prints simple
@@ -86,18 +94,11 @@ typedef struct var {
 	double	longestnd;	/* longest negative double */
 } VAR;
 
-struct pinfo {
-	struct kinfo_proc2 *ki;
-	double pcpu;
-};
 
-#define	OUTPUT(vent, kl, pi, ki, mode) do {				\
-	if ((vent)->var->flag & LWP)					\
-		((vent)->var->oproc)((void *)(kl), (vent), (mode));	\
-	else if ((vent)->var->type == PCPU)				\
-		((vent)->var->oproc)((void *)(pi), (vent), (mode));	\
-	else								\
-		((vent)->var->oproc)((void *)(ki), (vent), (mode));	\
+#define	OUTPUT(vent, kl, pi, ki, mode) do {		\
+	if ((vent)->var->flag & LWP)			\
+	    pi->li = kl;				\
+	((vent)->var->oproc)(pi, (vent), (mode));	\
 	} while (/*CONSTCOND*/ 0)
 
 #include "extern.h"

Reply via email to