Index: top/commands.c =================================================================== --- top/commands.c +++ top/commands.c @@ -100,6 +100,7 @@ o - specify sort order (vcsw, ivcsw, read, write, fault, total, jid, pid)\n", stdout); fputs("\ +p - display one process (+ selects all processes)\n\ P - toggle the displaying of per-CPU statistics\n\ r - renice a process\n\ s - change number of seconds to delay between updates\n\ Index: top/machine.h =================================================================== --- top/machine.h +++ top/machine.h @@ -75,6 +75,7 @@ int jail; /* show jail ID */ int swap; /* show swap usage */ int kidle; /* show per-CPU idle threads */ + pid_t pid; /* only this pid (unless pid == -1) */ char *command; /* only this command (unless == NULL) */ }; Index: top/machine.c =================================================================== --- top/machine.c +++ top/machine.c @@ -777,6 +777,7 @@ int show_self; int show_system; int show_uid; + int show_pid; int show_command; int show_kidle; @@ -847,6 +848,7 @@ show_self = sel->self == -1; show_system = sel->system; show_uid = sel->uid[0] != -1; + show_pid = sel->pid != -1; show_command = sel->command != NULL; show_kidle = sel->kidle; @@ -909,6 +911,9 @@ /* skip proc. that don't belong to the selected UID */ continue; + if (show_pid && pp->ki_pid != sel->pid) + continue; + *prefp++ = pp; active_procs++; } Index: top/top.c =================================================================== --- top/top.c +++ top/top.c @@ -278,8 +278,9 @@ char *order_name = NULL; int order_index = 0; fd_set readfds; + char old_system = No; - static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJwo"; + static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJwop"; /* these defines enumerate the "strchr"s of the commands in command_chars */ #define CMD_redraw 0 #define CMD_update 1 @@ -308,7 +309,8 @@ #define CMD_pcputog 23 #define CMD_jail 24 #define CMD_swaptog 25 -#define CMD_order 26 +#define CMD_order 26 +#define CMD_pid 27 /* set the buffer for stdout */ #ifdef DEBUG @@ -343,6 +345,7 @@ ps.jail = No; ps.swap = No; ps.kidle = Yes; + ps.pid = -1; ps.command = NULL; /* get preset options from the environment */ @@ -368,7 +371,7 @@ optind = 1; } - while ((i = getopt(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:tw")) != EOF) + while ((i = getopt(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:p:tw")) != EOF) { switch(i) { @@ -390,7 +393,8 @@ break; case 'S': /* show system processes */ - ps.system = !ps.system; + ps.system = Yes; + old_system = Yes; break; case 'I': /* show idle processes */ @@ -423,6 +427,19 @@ displays = i; } break; + case 'p': { + unsigned long long num; + const char *errstr; + + num = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr != NULL || !find_pid(num)) { + fprintf(stderr, "%s: unknown pid\n", optarg); + exit(1); + } + ps.pid = (pid_t)num; + ps.system = Yes; + break; + } case 's': if ((delay = atoi(optarg)) < 0 || (delay == 0 && getuid() != 0)) @@ -508,8 +525,8 @@ default: fprintf(stderr, -"Usage: %s [-abCHIijnPqStuvwz] [-d count] [-m io | cpu] [-o field] [-s time]\n" -" [-J jail] [-U username] [number]\n", +"Usage: %s [-abCHIijnPqStuvwz] [-d count] [-m io | cpu] [-o field] [-p pid]\n" +" [-s time] [-J jail] [-U username] [number]\n", myname); exit(1); } @@ -1100,6 +1117,7 @@ break; case CMD_viewsys: ps.system = !ps.system; + old_system = ps.system; break; case CMD_showargs: fmt_flags ^= FMT_SHOWARGS; @@ -1199,6 +1217,36 @@ reset_display(); putchar('\r'); break; + case CMD_pid: + new_message(MT_standout, + "Process id to show (+ for all): "); + if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) { + if (tempbuf2[0] == '+' && + tempbuf2[1] == '\0') { + ps.pid = (pid_t)-1; + ps.system = old_system; + } else { + unsigned long long num; + const char *errstr; + + num = strtonum(tempbuf2, 0, INT_MAX, + &errstr); + if (errstr != NULL || !find_pid(num)) { + new_message(MT_standout, + " %s: unknown pid", + tempbuf2); + no_command = Yes; + } else { + if (ps.system == No) + old_system = No; + ps.pid = (pid_t)num; + ps.system = Yes; + } + } + putchar('\r'); + } else + clear_message(); + break; default: new_message(MT_standout, " BAD CASE IN SWITCH!"); putchar('\r'); Index: top/top.xs =================================================================== --- top/top.xs +++ top/top.xs @@ -17,6 +17,11 @@ .BI \-m io | cpu ] [ .BI \-o field +] +.br +.ti +4 +[ +.BI \-p pid ] [ .BI \-s time ] [ @@ -177,6 +182,10 @@ \*(rqwrite\*(lq, \*(rqfault\*(lq, \*(rqvcsw\*(lq, \*(rqivcsw\*(lq, \*(lqjid\*(lq, \*(rqswap\*(lq or \*(rqpid\*(lq. .TP +.BI \-p pid +Show only the process +.IR pid . +.TP .BI \-J jail Show only those processes owned by .IR jail . @@ -319,6 +328,10 @@ but usually include: \*(lqcpu\*(rq, \*(lqres\*(rq, \*(lqsize\*(rq, \*(lqtime\*(rq. The default is cpu. .TP +.B p +Display a specific process (prompt for pid). +If the pid specified is simply \*(lq+\*(rq, then show all processes. +.TP .B e Display a list of system errors (if any) generated by the last .BR k ill Index: top/utils.h =================================================================== --- top/utils.h +++ top/utils.h @@ -21,4 +21,4 @@ char *format_k(int); char *format_k2(unsigned long long); int string_index(char *string, char **array); - +int find_pid(pid_t); Index: top/utils.c =================================================================== --- top/utils.c +++ top/utils.c @@ -17,9 +17,18 @@ #include "top.h" +#include +#include +#include + #include #include #include +#include +#include +#include + +void quit(int); int atoiwi(char *str) @@ -459,3 +468,27 @@ return(ret); } + +int +find_pid(pid_t pid) +{ + kvm_t *kd = NULL; + struct kinfo_proc *pbase = NULL; + int i, nproc; + + kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); + if (kd == NULL) + quit(23); + + pbase = kvm_getprocs(kd, KERN_PROC_PID, pid, &nproc); + if (pbase == NULL) + quit(23); + + if ((nproc == 1) && (pbase->ki_pid == pid)) { + printf("pid found!\n"); + return 1; + } + + exit(12); + return 0; +}