Hi,
Resubmitting this diff, as I've been unable to get an OK.
Original blurb:
> I'd like top(1)'s filter feature (-g) to search process arguments. This
> would make searching for (e.g.) Python scripts by name much easier. The
> current behaviour only searches the program name, which for scripts is
> the interpreter binary name (e.g. python2.7). Currently the best you
> could do to find a Python script by name is to filter for "python", then
> press "C" to enable argument display, then scan the args by eyeball.
>
> Here is a diff that allows searching of arguments, but only if
> arguments are currently being displayed.
Diff below. OK anyone. Pretty please?
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
--
Best Regards
Edd Barrett
http://www.theunixzoo.co.uk