Index: bin/ps/ps.1 =================================================================== --- bin/ps/ps.1 +++ bin/ps/ps.1 @@ -224,6 +224,9 @@ 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 +Display information about processes whose parent matches the specified +process IDs. .It Fl p Display information about processes which match the specified process IDs. .It Fl r Index: bin/ps/ps.c =================================================================== --- bin/ps/ps.c +++ bin/ps/ps.c @@ -170,12 +170,12 @@ "%cpu,%mem,command"; static char Zfmt[] = "label"; -#define PS_ARGS "AaCcde" OPT_LAZY_f "G:gHhjJ:LlM:mN:O:o:p:rSTt:U:uvwXxZ" +#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 +234,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"); @@ -352,6 +353,13 @@ */ nselectors++; break; + case 'P': + /* + * Non-standard option corresponding to Linux --ppid. + */ + add_list(&ppidlist, optarg); + nselectors++; + break; #if 0 case 'R': /*- @@ -558,6 +566,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