Date: Fri, 23 Nov 2018 19:41:54 +0100 From: Christian Barthel <bch@online.de> To: freebsd-hackers@freebsd.org Subject: top(1): adding grep like selection and system processes Message-ID: <878t1j1vrh.fsf@x230.onfire.org>
next in thread | raw e-mail | index | archive | help
--=-=-= Content-Type: text/plain Hello, I've added two features that I (personally) found useful in top(1): A grep-like feature to filter command names in top(1) (inspired by the OpenBSD top version). One example may be to filter out all current virtual machines by using "top -g bhyve" or interactively with "g bhyve". (there was already a selection field ps.command; so, perhaps someone is already working on a similar feature?). It is not possible to filter with a regular expression. The second flag is selection of system processes with -K or interactively toggle between user and system processes. I want to ask if this is of general interest for FreeBSD users or if its useful for someone else here? I've tested it on FreeBSD 13.0-CURRENT. Christian --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=top-grep-sysproc.patch Content-Description: top(1) patch to add grep-like feature and system process selection. diff --git a/usr.bin/top/commands.c b/usr.bin/top/commands.c index 88f4b0867d4..082f5fcc9af 100644 --- a/usr.bin/top/commands.c +++ b/usr.bin/top/commands.c @@ -59,10 +59,12 @@ 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}, + {'g', "grep command name", 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}, {'J', "display processes for only one jail (+ selects all jails)", false, CMD_jail}, + {'K', "toggle between system and user processes", false, CMD_kern}, {'k', "kill processes; send a signal to a list of processes", false, CMD_kill}, {'q', "quit" , true, CMD_quit}, {'m', "toggle the display between 'cpu' and 'io' modes", false, CMD_viewtog}, diff --git a/usr.bin/top/commands.h b/usr.bin/top/commands.h index 0071fbe62fc..75fe9756a56 100644 --- a/usr.bin/top/commands.h +++ b/usr.bin/top/commands.h @@ -46,6 +46,8 @@ enum cmd_id { CMD_order, CMD_pid , CMD_toggletid, + CMD_grep, + CMD_kern, }; struct command { diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c index 374c9da0edf..2fb5b5221b7 100644 --- a/usr.bin/top/machine.c +++ b/usr.bin/top/machine.c @@ -803,6 +803,13 @@ get_process_info(struct system_info *si, struct process_select *sel, /* skip self */ continue; + if (sel->command && strncmp(pp->ki_comm, sel->command, COMMLEN)) + /* skip not matching commands */ + continue; + + if (!sel->user && !(pp->ki_flag & P_SYSTEM) && sel->pid == -1) + continue; + if (!sel->system && (pp->ki_flag & P_SYSTEM) && sel->pid == -1) /* skip system process */ continue; diff --git a/usr.bin/top/machine.h b/usr.bin/top/machine.h index c3c7777d910..40a36e947b9 100644 --- a/usr.bin/top/machine.h +++ b/usr.bin/top/machine.h @@ -63,6 +63,7 @@ struct process_select bool idle; /* show idle processes */ bool self; /* show self */ bool system; /* show system processes */ + bool user; /* show user processes */ bool thread; /* show threads */ bool thread_id; /* show thread ids */ #define TOP_MAX_UIDS 8 @@ -73,7 +74,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 */ diff --git a/usr.bin/top/top.c b/usr.bin/top/top.c index 2279479409b..3a30bf40d9a 100644 --- a/usr.bin/top/top.c +++ b/usr.bin/top/top.c @@ -271,6 +271,7 @@ main(int argc, char *argv[]) ps.idle = true; ps.self = true; ps.system = false; + ps.user = true; reset_uids(); ps.thread = false; ps.wcpu = 1; @@ -305,14 +306,20 @@ main(int argc, char *argv[]) optind = 1; } - while ((i = getopt_long(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:p:Ttw", longopts, NULL)) != EOF) + while ((i = getopt_long(ac, av, "CSIHKPabg:ijJ:nquvzs:d:U:m:o:p:Ttw", longopts, NULL)) != EOF) { switch(i) { case 'v': /* show version number */ errx(0, "version FreeBSD"); break; - + case 'g': + ps.command = strdup(optarg); + break; + case 'K': + ps.user = false; + ps.system = true; + break; case 'u': /* toggle uid/username display */ do_unames = !do_unames; break; @@ -870,7 +877,15 @@ main(int argc, char *argv[]) topn = newval; } break; - + case CMD_kern: + if (ps.user == false) { + ps.user = true; + ps.system = false; + } else { + ps.user = false; + ps.system = true; + } + break; case CMD_delay: /* new seconds delay */ new_message(MT_standout, "Seconds to delay: "); if ((i = readline(tempbuf1, 8, true)) > -1) @@ -1027,7 +1042,19 @@ main(int argc, char *argv[]) reset_display(); putchar('\r'); break; + case CMD_grep: + new_message(MT_standout, + "command name: "); + if (readline(tempbuf2, sizeof(tempbuf2), false) > 0) { + if (ps.command != NULL) + free(ps.command); + if (tempbuf2[0] == '+' && tempbuf2[1] == '\0') + ps.command = NULL; + else + ps.command = strdup(tempbuf2); + } + break; case CMD_jail: new_message(MT_standout, "Jail to show (+ for all): "); --=-=-=--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?878t1j1vrh.fsf>