Index: head/contrib/top/machine.h =================================================================== --- head/contrib/top/machine.h +++ head/contrib/top/machine.h @@ -70,7 +70,8 @@ int self; /* show self */ int system; /* show system processes */ int thread; /* show threads */ - int uid; /* only this uid (unless uid == -1) */ +#define TOP_MAX_UIDS 8 + int uid[TOP_MAX_UIDS]; /* only these uids (unless uid[0] == -1) */ int wcpu; /* show weighted cpu */ int jid; /* only this jid (unless jid == -1) */ int jail; /* show jail ID */ Index: head/contrib/top/top.c =================================================================== --- head/contrib/top/top.c +++ head/contrib/top/top.c @@ -134,7 +134,110 @@ void reset_display(void); +static void +reset_uids() +{ + for (size_t i = 0; i < TOP_MAX_UIDS; ++i) + ps.uid[i] = -1; +} +static int +add_uid(int uid) +{ + size_t i = 0; + + /* Add the uid if there's room */ + for (; i < TOP_MAX_UIDS; ++i) + { + if (ps.uid[i] == -1 || ps.uid[i] == uid) + { + ps.uid[i] = uid; + break; + } + } + + return (i == TOP_MAX_UIDS); +} + +static void +rem_uid(int uid) +{ + size_t i = 0; + size_t where = TOP_MAX_UIDS; + + /* Look for the user to remove - no problem if it's not there */ + for (; i < TOP_MAX_UIDS; ++i) + { + if (ps.uid[i] == -1) + break; + if (ps.uid[i] == uid) + where = i; + } + + /* Make sure we don't leave a hole in the middle */ + if (where != TOP_MAX_UIDS) + { + ps.uid[where] = ps.uid[i-1]; + ps.uid[i-1] = -1; + } +} + +static int +handle_user(char *buf, size_t buflen) +{ + int rc = 0; + int uid = -1; + char *buf2 = buf; + + new_message(MT_standout, "Username to show (+ for all): "); + if (readline(buf, buflen, No) <= 0) + { + clear_message(); + return rc; + } + + if (buf[0] == '+' || buf[0] == '-') + { + if (buf[1] == '\0') + { + reset_uids(); + goto end; + } + else + ++buf2; + } + + if ((uid = userid(buf2)) == -1) + { + new_message(MT_standout, " %s: unknown user", buf2); + rc = 1; + goto end; + } + + if (buf2 == buf) + { + reset_uids(); + ps.uid[0] = uid; + goto end; + } + + if (buf[0] == '+') + { + if (add_uid(uid)) + { + new_message(MT_standout, " too many users, reset with '+'"); + rc = 1; + goto end; + } + } + else + rem_uid(uid); + +end: + putchar('\r'); + return rc; +} + int main(argc, argv) @@ -252,7 +355,7 @@ ps.idle = Yes; ps.self = -1; ps.system = No; - ps.uid = -1; + reset_uids(); ps.thread = No; ps.wcpu = 1; ps.jid = -1; @@ -299,7 +402,7 @@ break; case 'U': /* display only username's processes */ - if ((ps.uid = userid(optarg)) == -1) + if ((ps.uid[0] = userid(optarg)) == -1) { fprintf(stderr, "%s: unknown user\n", optarg); exit(1); @@ -1004,31 +1107,8 @@ break; case CMD_user: - new_message(MT_standout, - "Username to show (+ for all): "); - if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) - { - if (tempbuf2[0] == '+' && - tempbuf2[1] == '\0') - { - ps.uid = -1; - } - else if ((i = userid(tempbuf2)) == -1) - { - new_message(MT_standout, - " %s: unknown user", tempbuf2); - no_command = Yes; - } - else - { - ps.uid = i; - } - putchar('\r'); - } - else - { - clear_message(); - } + if (handle_user(tempbuf2, sizeof(tempbuf2))) + no_command = Yes; break; case CMD_thrtog: Index: head/contrib/top/top.xs =================================================================== --- head/contrib/top/top.xs +++ head/contrib/top/top.xs @@ -307,9 +307,11 @@ .IR renice (8)). .TP .B u -Display only processes owned by a specific username (prompt for username). -If the username specified is simply \*(lq+\*(rq, then processes belonging -to all users will be displayed. +Display only processes owned by a specific set of usernames (prompt for +username). If the username specified is simply \*(lq+\*(rq or \*(lq-\*(rq, +then processes belonging to all users will be displayed. Usernames can be added +to and removed from the set by prepending them with \*(lq+\*(rq and +\*(lq-\*(rq, respectively. .TP .B o Change the order in which the display is sorted. This command is not Index: head/usr.bin/top/machine.c =================================================================== --- head/usr.bin/top/machine.c +++ head/usr.bin/top/machine.c @@ -273,7 +273,19 @@ 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 +find_uid(uid_t needle, int *haystack) +{ + size_t i = 0; + + for (; i < TOP_MAX_UIDS; ++i) + if ((uid_t)haystack[i] == needle) + return 1; + return 0; +} + void toggle_pcpustats(void) { @@ -847,7 +859,7 @@ show_jid = sel->jid != -1; show_self = sel->self == -1; show_system = sel->system; - show_uid = sel->uid != -1; + show_uid = sel->uid[0] != -1; show_command = sel->command != NULL; show_kidle = sel->kidle; @@ -906,7 +918,7 @@ /* skip proc. that don't belong to the selected JID */ continue; - if (show_uid && pp->ki_ruid != (uid_t)sel->uid) + if (show_uid && !find_uid(pp->ki_ruid, sel->uid)) /* skip proc. that don't belong to the selected UID */ continue;