Hey, Thanks all for the comments.
On Wed, Feb 10, 2016 at 04:27:38PM -0800, patrick keshishian wrote: > NULL pointer dereference is possible here. > > Also, unclear why you need both arg and args variables. ^ Fix these and make cmd_matches() static. Updated diff: Index: machine.c =================================================================== RCS file: /home/edd/cvsync/src/usr.bin/top/machine.c,v retrieving revision 1.85 diff -u -p -r1.85 machine.c --- machine.c 20 Aug 2015 22:32:42 -0000 1.85 +++ machine.c 12 Feb 2016 18:52:31 -0000 @@ -57,6 +57,8 @@ static int swapmode(int *, int *); static char *state_abbr(struct kinfo_proc *); static char *format_comm(struct kinfo_proc *); +static int cmd_matches(struct kinfo_proc *proc, char *cmd); +static char **get_proc_args(struct kinfo_proc *kp); /* get_process_info passes back a handle. This is what it looks like: */ @@ -360,6 +362,61 @@ getprocs(int op, int arg, int *cnt) return (procbase); } +static char ** +get_proc_args(struct kinfo_proc *kp) +{ + static char **s; + size_t siz = 100; + int mib[4]; + + for (;; siz *= 2) { + if ((s = realloc(s, siz)) == NULL) + err(1, NULL); + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = kp->p_pid; + mib[3] = KERN_PROC_ARGV; + if (sysctl(mib, 4, s, &siz, NULL, 0) == 0) + break; + if (errno != ENOMEM) + return (NULL); + } + return (s); +} + +static int +cmd_matches(struct kinfo_proc *proc, char *term) +{ + extern int show_args; + char **args = NULL; + + if (!term) { + /* No command filter set */ + return (1); + } else { + /* Filter set, process name needs to contain term */ + if (strstr(proc->p_comm, term)) { + return (1); + } + /* If showing arguments, search those as well */ + if (show_args) { + args = get_proc_args(proc); + + if (args == NULL) { + /* Failed to get args, so can't search them */ + return (0); + } + + while (*args != NULL) { + if (strstr(*args, term)) + return (1); + args++; + } + } + } + return (0); +} + caddr_t get_process_info(struct system_info *si, struct process_select *sel, int (*compare) (const void *, const void *)) @@ -421,8 +478,7 @@ get_process_info(struct system_info *si, (!hide_uid || pp->p_ruid != sel->huid) && (!show_uid || pp->p_ruid == sel->uid) && (!show_pid || pp->p_pid == sel->pid) && - (!show_cmd || strstr(pp->p_comm, - sel->command))) { + (!show_cmd || cmd_matches(pp, sel->command))) { *prefp++ = pp; active_procs++; } @@ -462,27 +518,17 @@ state_abbr(struct kinfo_proc *pp) static char * format_comm(struct kinfo_proc *kp) { - static char **s, buf[MAX_COLS]; - size_t siz = 100; - char **p; - int mib[4]; + static char buf[MAX_COLS]; + char **p, **s; extern int show_args; if (!show_args) return (kp->p_comm); - for (;; siz *= 2) { - if ((s = realloc(s, siz)) == NULL) - err(1, NULL); - mib[0] = CTL_KERN; - mib[1] = KERN_PROC_ARGS; - mib[2] = kp->p_pid; - mib[3] = KERN_PROC_ARGV; - if (sysctl(mib, 4, s, &siz, NULL, 0) == 0) - break; - if (errno != ENOMEM) - return (kp->p_comm); - } + s = get_proc_args(kp); + if (s == NULL) + return (kp->p_comm); + buf[0] = '\0'; for (p = s; *p != NULL; p++) { if (p != s) Index: top.1 =================================================================== RCS file: /home/edd/cvsync/src/usr.bin/top/top.1,v retrieving revision 1.66 diff -u -p -r1.66 top.1 --- top.1 6 May 2015 07:53:29 -0000 1.66 +++ top.1 6 Feb 2016 15:03:50 -0000 @@ -107,7 +107,8 @@ The default is 1 for dumb terminals. .It Fl g Ar string Display only processes that contain .Ar string -in their command name. +in their command name. If displaying of arguments is enabled, the +arguments are searched too. .It Fl H Show process threads in the display. Normally, only the main process is shown. @@ -305,7 +306,8 @@ command. .It g Ar string Display only processes that contain .Ar string -in their command name. +in their command name. If displaying of arguments is enabled, the +arguments are searched too. .Sq g+ shows all processes. .It H -- Best Regards Edd Barrett http://www.theunixzoo.co.uk