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"