Enhance top(1) to filter on multiple usernames
Reviewed by: cognet, bapt Approved by: cognet MFC after: 1 week Relnotes: yes Differential Revision: https://reviews.freebsd.org/D11840
This commit is contained in:
parent
c69b68f502
commit
f9995000bc
@ -70,7 +70,8 @@ struct process_select
|
||||
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 */
|
||||
|
@ -134,6 +134,109 @@ void (*d_process)(int line, char *thisline) = i_process;
|
||||
|
||||
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 @@ char *argv[];
|
||||
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 @@ char *argv[];
|
||||
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 @@ char *argv[];
|
||||
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:
|
||||
|
@ -307,9 +307,11 @@ This acts similarly to the command
|
||||
.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
|
||||
|
@ -273,6 +273,18 @@ static const char *format_nice(const struct kinfo_proc *pp);
|
||||
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 @@ get_process_info(struct system_info *si, struct process_select *sel,
|
||||
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 @@ get_process_info(struct system_info *si, struct process_select *sel,
|
||||
/* 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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user