Index: bin/ps/ps.1 =================================================================== --- bin/ps/ps.1 +++ bin/ps/ps.1 @@ -165,7 +165,7 @@ .Cm user , pid , ppid , pgid , sid , jobc , state , tt , time , and .Cm command . -.It Fl J +.It Fl J , Fl Fl jail Display information about processes which match the specified jail IDs. This may be either the .Cm jid @@ -224,8 +224,11 @@ option. So the header texts for multiple keywords can be changed. If all keywords have empty header texts, no header line is written. -.It Fl p +.It Fl p , Fl Fl pid Display information about processes which match the specified process IDs. +.It Fl P , Fl Fl ppid +Display information about processes whose parent matches the specified +process IDs. .It Fl r Sort by current CPU usage, instead of the combination of controlling terminal and process ID. @@ -235,7 +238,7 @@ .It Fl T Display information about processes attached to the device associated with the standard input. -.It Fl t +.It Fl t , Fl Fl tty Display information about processes attached to the specified terminal devices. Full pathnames, as well as abbreviations (see explanation of the Index: bin/ps/ps.c =================================================================== --- bin/ps/ps.c +++ bin/ps/ps.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -170,12 +171,20 @@ "%cpu,%mem,command"; static char Zfmt[] = "label"; -#define PS_ARGS "AaCcde" OPT_LAZY_f "G:gHhjJ:LlM:mN:O:o:p:rSTt:U:uvwXxZ" +static struct option longopts[] = { + { "jail", required_argument, NULL, 'J' }, + { "pid", required_argument, NULL, 'p' }, + { "ppid", required_argument, NULL, 'P' }, + { "tty", required_argument, NULL, 't' }, + { NULL, 0, NULL, 0 } +}; + +#define PS_ARGS "AaCcde" OPT_LAZY_f "G:gHhjJ:LlM:mN:O:o:p:P:rSTt:U:uvwXxZ" int main(int argc, char *argv[]) { - struct listinfo gidlist, jidlist, pgrplist, pidlist; + struct listinfo gidlist, jidlist, pgrplist, pidlist, ppidlist; struct listinfo ruidlist, sesslist, ttylist, uidlist; struct kinfo_proc *kp; KINFO *kinfo = NULL, *next_KINFO; @@ -234,6 +243,7 @@ init_list(&jidlist, addelem_jid, sizeof(int), "jail id"); init_list(&pgrplist, addelem_pid, sizeof(pid_t), "process group"); init_list(&pidlist, addelem_pid, sizeof(pid_t), "process id"); + init_list(&ppidlist, addelem_pid, sizeof(pid_t), "parent process id"); init_list(&ruidlist, addelem_uid, sizeof(uid_t), "ruser"); init_list(&sesslist, addelem_pid, sizeof(pid_t), "session id"); init_list(&ttylist, addelem_tty, sizeof(dev_t), "tty"); @@ -245,7 +255,7 @@ if (argc < 0) exit(1); - while ((ch = getopt(argc, argv, PS_ARGS)) != -1) + while ((ch = getopt_long(argc, argv, PS_ARGS, longopts, NULL)) != -1) switch (ch) { case 'A': /* @@ -352,6 +362,13 @@ */ nselectors++; break; + case 'P': + /* + * Non-standard option corresponding to Linux --ppid. + */ + add_list(&ppidlist, optarg); + nselectors++; + break; #if 0 case 'R': /*- @@ -558,6 +575,11 @@ if (kp->ki_pid == pidlist.l.pids[elem]) goto keepit; } + if (ppidlist.count > 0) { + for (elem = 0; elem < ppidlist.count; elem++) + if (kp->ki_ppid == ppidlist.l.pids[elem]) + goto keepit; + } /* * Note that we had to process pidlist before * filtering out processes which do not have @@ -1453,10 +1475,11 @@ { #define SINGLE_OPTS "[-aCcde" OPT_LAZY_f "HhjlmrSTuvwXxZ]" - (void)xo_error("%s\n%s\n%s\n%s\n", + (void)xo_error("%s\n%s\n%s\n%s\n%s\n", "usage: ps " SINGLE_OPTS " [-O fmt | -o fmt] [-G gid[,gid...]]", - " [-J jid[,jid...]] [-M core] [-N system]", - " [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]", + " [-J|--jail jid[,jid...]] [-M core] [-N system]", + " [-p|--pid pid[,pid...]] [-P|--ppid pid[,pid...]]", + " [-t tty[,tty...]] [-U user[,user...]]", " ps [-L]"); exit(1); }