1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-23 07:31:31 +00:00

top(1): support command name and argument grepping

Obtained from:  OpenBSD
Reviewed by:	imp@
Pull Request:	https://github.com/freebsd/freebsd-src/pull/479
This commit is contained in:
John Grafton 2021-06-16 15:40:21 -04:00 committed by Warner Losh
parent 0d9e8c286d
commit a00d703f2f
7 changed files with 60 additions and 1 deletions

View File

@ -59,6 +59,7 @@ const struct command all_commands[] =
{'H', "toggle the displaying of threads", false, CMD_thrtog},
{'h', "show this help text", true, CMD_help},
{'?', NULL, true, CMD_help},
{'/', "filter on command name (+ selects all commands)", false, CMD_grep},
{'i', "toggle the displaying of idle processes", false, CMD_idletog},
{'I', NULL, false, CMD_idletog},
{'j', "toggle the displaying of jail ID", false, CMD_jidtog},

View File

@ -24,6 +24,7 @@ enum cmd_id {
CMD_update,
CMD_quit,
CMD_help,
CMD_grep,
CMD_errors,
CMD_number,
CMD_delay,

View File

@ -224,6 +224,7 @@ static void getsysctl(const char *name, void *ptr, size_t len);
static int swapmode(int *retavail, int *retfree);
static void update_layout(void);
static int find_uid(uid_t needle, int *haystack);
static int cmd_matches(struct kinfo_proc *, const char *);
static int
find_uid(uid_t needle, int *haystack)
@ -869,6 +870,10 @@ get_process_info(struct system_info *si, struct process_select *sel,
if (sel->pid != -1 && pp->ki_pid != sel->pid)
continue;
if (!cmd_matches(pp, sel->command))
/* skip proc. that doesn't match grep string */
continue;
*prefp++ = pp;
active_procs++;
}
@ -887,6 +892,36 @@ get_process_info(struct system_info *si, struct process_select *sel,
return (&handle);
}
static int
cmd_matches(struct kinfo_proc *proc, const char *term)
{
extern int show_args;
char **args = NULL;
if (!term) {
/* No command filter set */
return 1;
} else {
/* Filter set, does process name contain term? */
if (strstr(proc->ki_comm, term))
return 1;
/* Search arguments only if arguments are displayed */
if (show_args) {
args = kvm_getargv(kd, proc, 1024);
if (args == NULL) {
/* Failed to get arguments so can't search them */
return 0;
}
while (*args != NULL) {
if (strstr(*args, term))
return 1;
args++;
}
}
}
return 0;
}
char *
format_next_process(struct handle * xhandle, char *(*get_userid)(int), int flags)
{

View File

@ -75,7 +75,7 @@ struct process_select
bool swap; /* show swap usage */
bool kidle; /* show per-CPU idle threads */
int pid; /* only this pid (unless pid == -1) */
const char *command; /* only this command (unless == NULL) */
char *command; /* only this command (unless == NULL) */
};
/* routines defined by the machine dependent module */

View File

@ -243,6 +243,11 @@ Remember that the next display counts as one, so typing
will make
.Nm
show one final display and then immediately exit.
.It /
Display only processes that contain the specified string in their
command name.
If displaying arguments is enabled, the arguments are searched
too. '+' shows all processes.
.It m
Toggle the display between 'cpu' and 'io' modes.
.It n or #

View File

@ -53,6 +53,7 @@ typedef void sigret_t;
static char stdoutbuf[Buffersize];
static int fmt_flags = 0;
int show_args = false;
int pcpu_stats = false;
/* signal handling routines */
@ -907,6 +908,19 @@ main(int argc, const char *argv[])
}
break;
case CMD_grep: /* grep command name */
new_message(MT_standout,
"Grep command name: ");
if (readline(tempbuf1, sizeof(tempbuf1), false) > 0) {
free(ps.command);
if (tempbuf1[0] == '+' && tempbuf1[1] == '\0') {
ps.command = NULL;
} else if ((ps.command = strdup(tempbuf1)) == NULL)
quit(1);
}
clear_message();
break;
case CMD_displays: /* change display count */
new_message(MT_standout,
"Displays to show (currently %s): ",
@ -1025,6 +1039,7 @@ main(int argc, const char *argv[])
break;
case CMD_showargs:
fmt_flags ^= FMT_SHOWARGS;
show_args = fmt_flags & FMT_SHOWARGS;
new_message(MT_standout | MT_delayed,
" %sisplaying process arguments.",
fmt_flags & FMT_SHOWARGS ? "D" : "Not d");

View File

@ -37,6 +37,8 @@ extern pid_t mypid;
extern int (*compares[])(const void*, const void*);
extern int show_args;
const char* kill_procs(char *);
const char* renice_procs(char *);