Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Aug 2017 15:08:50 +0000 (UTC)
From:      Pietro Cerutti <gahr@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r322509 - in stable/11: contrib/top usr.bin/top
Message-ID:  <201708141508.v7EF8oRu014465@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gahr (ports committer)
Date: Mon Aug 14 15:08:49 2017
New Revision: 322509
URL: https://svnweb.freebsd.org/changeset/base/322509

Log:
  MFC r322139
  
  Enhance top(1) to filter on multiple usernames
  
  Reviewed by:	cognet, bapt
  Approved by:	cognet
  Relnotes:		yes
  Differential Revision:	https://reviews.freebsd.org/D11840

Modified:
  stable/11/contrib/top/machine.h
  stable/11/contrib/top/top.c
  stable/11/contrib/top/top.xs
  stable/11/usr.bin/top/machine.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/contrib/top/machine.h
==============================================================================
--- stable/11/contrib/top/machine.h	Mon Aug 14 14:16:56 2017	(r322508)
+++ stable/11/contrib/top/machine.h	Mon Aug 14 15:08:49 2017	(r322509)
@@ -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 */

Modified: stable/11/contrib/top/top.c
==============================================================================
--- stable/11/contrib/top/top.c	Mon Aug 14 14:16:56 2017	(r322508)
+++ stable/11/contrib/top/top.c	Mon Aug 14 15:08:49 2017	(r322509)
@@ -133,7 +133,110 @@ void (*d_process)() = 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)
 
@@ -251,7 +354,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;
@@ -298,7 +401,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);
@@ -1003,31 +1106,8 @@ restart:
 				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:

Modified: stable/11/contrib/top/top.xs
==============================================================================
--- stable/11/contrib/top/top.xs	Mon Aug 14 14:16:56 2017	(r322508)
+++ stable/11/contrib/top/top.xs	Mon Aug 14 15:08:49 2017	(r322509)
@@ -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

Modified: stable/11/usr.bin/top/machine.c
==============================================================================
--- stable/11/usr.bin/top/machine.c	Mon Aug 14 14:16:56 2017	(r322508)
+++ stable/11/usr.bin/top/machine.c	Mon Aug 14 15:08:49 2017	(r322509)
@@ -273,7 +273,19 @@ static const char *format_nice(const struct kinfo_proc
 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 proces
 	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 proces
 			/* 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;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201708141508.v7EF8oRu014465>