]> granicus.if.org Git - procps-ng/commitdiff
library: repair <pids> api boo-boo in the 'select' i/f
authorJim Warner <james.warner@comcast.net>
Sat, 7 Aug 2021 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@dropbear.xyz>
Mon, 9 Aug 2021 12:03:23 +0000 (22:03 +1000)
The patch referenced below corrected some flaws in the
procps_pids_select implementation. But, there remained
one flaw which this commit will now hopefully address.

Rather than assume callers wished to select only tasks
and not threads meant a command like 'top -H -p 10329'
works differently under newlib than release 3.3.17. It
fails to honor the '-H' (threads) switch under newlib.

So, to fix that oops, we'll allow that select function
to get threads or tasks depending on its 'which' parm.

Reference(s):
. Oct 2015, some flaws corrected
commit bc616b361596bc3008800de839b88446508cfdd0

Signed-off-by: Jim Warner <james.warner@comcast.net>
proc/pids.c
proc/pids.h
proc/readproc.c

index fae340e028651de1958dfc2fa292cc7a7ffd5542..d7897c5efe92e3fe5659201fee2a29910b432c3d 100644 (file)
@@ -1214,11 +1214,27 @@ PROCPS_EXPORT int procps_pids_new (
             , __FILE__, PIDS_SELECT_PID, PROC_PID);
         failed = 1;
     }
+    if (PIDS_SELECT_PID_THREADS != PIDS_SELECT_PID + 1) {
+        fprintf(stderr, "%s: header error: PIDS_SELECT_PID_THREADS = 0x%04x, should be 0x%04x\n"
+            , __FILE__, PIDS_SELECT_PID_THREADS, PIDS_SELECT_PID + 1);
+        failed = 1;
+    }
     if (PIDS_SELECT_UID != PROC_UID) {
         fprintf(stderr, "%s: header error: PIDS_SELECT_UID = 0x%04x, PROC_UID = 0x%04x\n"
             , __FILE__, PIDS_SELECT_UID, PROC_UID);
         failed = 1;
     }
+    if (PIDS_SELECT_UID_THREADS != PIDS_SELECT_UID + 1) {
+        fprintf(stderr, "%s: header error: PIDS_SELECT_UID_THREADS = 0x%04x, should be 0x%04x\n"
+            , __FILE__, PIDS_SELECT_UID_THREADS, PIDS_SELECT_UID + 1);
+        failed = 1;
+    }
+    // our select() function & select enumerators assume the following ...
+    if (PIDS_FETCH_THREADS_TOO != 1) {
+        fprintf(stderr, "%s: header error: PIDS_FETCH_THREADS_TOO = %d, should be 1\n"
+            , __FILE__, PIDS_FETCH_THREADS_TOO);
+        failed = 1;
+    }
     if (failed) _Exit(EXIT_FAILURE);
 #endif
 
@@ -1533,7 +1549,8 @@ PROCPS_EXPORT struct pids_fetch *procps_pids_select (
         return NULL;
     if (numthese < 1 || numthese > FILL_ID_MAX)
         return NULL;
-    if (which != PIDS_SELECT_PID && which != PIDS_SELECT_UID)
+    if ((which != PIDS_SELECT_PID && which != PIDS_SELECT_UID)
+    && ((which != PIDS_SELECT_PID_THREADS && which != PIDS_SELECT_UID_THREADS)))
         return NULL;
     /* with items & numitems technically optional at 'new' time, it's
        expected 'reset' will have been called -- but just in case ... */
@@ -1547,7 +1564,7 @@ PROCPS_EXPORT struct pids_fetch *procps_pids_select (
 
     if (!pids_oldproc_open(&info->fetch_PT, (info->oldflags | which), ids, numthese))
         return NULL;
-    info->read_something = readproc;
+    info->read_something = (which & PIDS_FETCH_THREADS_TOO) ? readeither : readproc;
 
     rc = pids_stacks_fetch(info);
 
index a14a28d4bd9ded625ebfca91a62f91b7249ef087..2d6e33598a69ee6f0fef49a48ec4322508866a8b 100644 (file)
@@ -189,8 +189,10 @@ enum pids_fetch_type {
 };
 
 enum pids_select_type {
-    PIDS_SELECT_PID  = 0x10000,
-    PIDS_SELECT_UID  = 0x20000
+    PIDS_SELECT_PID         = 0x10000,
+    PIDS_SELECT_PID_THREADS = 0x10001,
+    PIDS_SELECT_UID         = 0x20000,
+    PIDS_SELECT_UID_THREADS = 0x20001
 };
 
 enum pids_sort_order {
index e52b6a223be2032f2f48b7ad0e18509f6f41f806..660450461e76ecaf3406f71b571fed07cefa3da9 100644 (file)
@@ -1126,7 +1126,7 @@ static proc_t *simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons
         goto next_proc;
 
     if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid))
-        goto next_proc;                 /* not one of the requested uids */
+        goto next_proc;                      /* not one of the requested uids */
 
     p->euid = sb.st_uid;                        /* need a way to get real uid */
     p->egid = sb.st_gid;                        /* need a way to get real gid */
@@ -1248,8 +1248,8 @@ static proc_t *simple_readtask(PROCTAB *restrict const PT, proc_t *restrict cons
     if (stat(path, &sb) == -1)                  /* no such dirent (anymore) */
         goto next_task;
 
-//  if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid))
-//      goto next_task;                         /* not one of the requested uids */
+    if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid))
+        goto next_task;                      /* not one of the requested uids */
 
     t->euid = sb.st_uid;                        /* need a way to get real uid */
     t->egid = sb.st_gid;                        /* need a way to get real gid */