]> granicus.if.org Git - procps-ng/commitdiff
fix "ps sm" bug involving 1-thread-proc optimization
authoralbert <>
Sat, 17 Jun 2006 04:14:57 +0000 (04:14 +0000)
committeralbert <>
Sat, 17 Jun 2006 04:14:57 +0000 (04:14 +0000)
NEWS
pgrep.c
proc/readproc.c
proc/readproc.h

diff --git a/NEWS b/NEWS
index 228b7406f5a62898f2d7149eab8b9e3ef1b957a8..6509331118d9b3a32298313c050961999536bd6c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,9 @@
 procps-3.2.6 --> procps-3.2.7
+
 top: document H option -- thanks Tony Ernst
 top: terabytes -- thanks Tony Ernst
 ps: SCHED_BATCH is B
+ps: fix s format (signals) output with thread display
 
 procps-3.2.5 --> procps-3.2.6
 
diff --git a/pgrep.c b/pgrep.c
index 2897424276425bb07292cd4a59577d8c9dc4cb32..af1e90b7a142a894904a57371ca0aa844dff48ca 100644 (file)
--- a/pgrep.c
+++ b/pgrep.c
@@ -83,7 +83,7 @@ split_list (const char *restrict str, int (*convert)(const char *, union el *))
        int i = 1, size = 32;
        union el *list;
 
-       list = malloc (size * sizeof (union el));
+       list = malloc (size * sizeof *list);
        if (list == NULL)
                exit (3);
 
@@ -97,7 +97,7 @@ split_list (const char *restrict str, int (*convert)(const char *, union el *))
                        exit (2);
                if (i == size) {
                        size *= 2;
-                       list = realloc (list, size * sizeof (union el));
+                       list = realloc (list, size * sizeof *list);
                        if (list == NULL)
                                exit (3);
                }
@@ -112,7 +112,7 @@ split_list (const char *restrict str, int (*convert)(const char *, union el *))
        } else {
                list[0].num = i - 1;
        }
-       return (list);
+       return list;
 }
 
 /* strict_atol returns a Boolean: TRUE if the input string contains a
@@ -138,7 +138,7 @@ strict_atol (const char *restrict str, long *restrict value)
                res += *str - '0';
        }
        *value = sign * res;
-       return (1);
+       return 1;
 }
 
 static int
@@ -153,10 +153,10 @@ conv_uid (const char *restrict name, union el *restrict e)
        if (pwd == NULL) {
                fprintf (stderr, "%s: invalid user name: %s\n",
                         progname, name);
-               return (0);
+               return 0;
        }
        e->num = pwd->pw_uid;
-       return (1);
+       return 1;
 }
 
 
@@ -166,16 +166,16 @@ conv_gid (const char *restrict name, union el *restrict e)
        struct group *grp;
 
        if (strict_atol (name, &e->num))
-               return (1);
+               return 1;
 
        grp = getgrnam (name);
        if (grp == NULL) {
                fprintf (stderr, "%s: invalid group name: %s\n",
                         progname, name);
-               return (0);
+               return 0;
        }
        e->num = grp->gr_gid;
-       return (1);
+       return 1;
 }
 
 
@@ -185,11 +185,11 @@ conv_pgrp (const char *restrict name, union el *restrict e)
        if (! strict_atol (name, &e->num)) {
                fprintf (stderr, "%s: invalid process group: %s\n",
                         progname, name);
-               return (0);
+               return 0;
        }
        if (e->num == 0)
                e->num = getpgrp ();
-       return (1);
+       return 1;
 }
 
 
@@ -199,11 +199,11 @@ conv_sid (const char *restrict name, union el *restrict e)
        if (! strict_atol (name, &e->num)) {
                fprintf (stderr, "%s: invalid session id: %s\n",
                         progname, name);
-               return (0);
+               return 0;
        }
        if (e->num == 0)
                e->num = getsid (0);
-       return (1);
+       return 1;
 }
 
 
@@ -213,9 +213,9 @@ conv_num (const char *restrict name, union el *restrict e)
        if (! strict_atol (name, &e->num)) {
                fprintf (stderr, "%s: not a number: %s\n",
                         progname, name);
-               return (0);
+               return 0;
        }
-       return (1);
+       return 1;
 }
 
 
@@ -223,7 +223,7 @@ static int
 conv_str (const char *restrict name, union el *restrict e)
 {
        e->str = strdup (name);
-       return (1);
+       return 1;
 }
 
 
@@ -240,7 +240,7 @@ match_numlist (long value, const union el *restrict list)
                                found = 1;
                }
        }
-       return (found);
+       return found;
 }
 
 static int
@@ -256,7 +256,7 @@ match_strlist (const char *restrict value, const union el *restrict list)
                                found = 1;
                }
        }
-       return (found);
+       return found;
 }
 
 static void
@@ -310,7 +310,7 @@ do_openproc (void)
        } else {
                ptp = openproc (flags);
        }
-       return (ptp);
+       return ptp;
 }
 
 static regex_t *
@@ -346,7 +346,7 @@ do_regcomp (void)
 }
 
 static union el *
-select_procs (void)
+select_procs (int *num)
 {
        PROCTAB *ptp;
        proc_t task;
@@ -359,7 +359,7 @@ select_procs (void)
        union el *list;
        char cmd[4096];
 
-       list = malloc (size * sizeof (union el));
+       list = malloc (size * sizeof *list);
        if (list == NULL)
                exit (3);
 
@@ -450,14 +450,13 @@ select_procs (void)
                        if (opt_long) {
                                char buff[5096];  // FIXME
                                sprintf (buff, "%d %s", task.XXXID, cmd);
-                               list[++matches].str = strdup (buff);
+                               list[matches++].str = strdup (buff);
                        } else {
-                               list[++matches].num = task.XXXID;
+                               list[matches++].num = task.XXXID;
                        }
                        if (matches == size) {
                                size *= 2;
-                               list = realloc (list,
-                                               size * sizeof (union el));
+                               list = realloc(list, size * sizeof *list);
                                if (list == NULL)
                                        exit (3);
                        }
@@ -467,8 +466,8 @@ select_procs (void)
        }
        closeproc (ptp);
 
-       list[0].num = matches;
-       return (list);
+       *num = matches;
+       return list;
 }
 
 
@@ -607,13 +606,14 @@ int
 main (int argc, char **argv)
 {
        union el *procs;
+       int num;
 
        parse_opts (argc, argv);
 
-       procs = select_procs ();
+       procs = select_procs (&num);
        if (i_am_pkill) {
                int i;
-               for (i = 1; i <= procs[0].num; i++) {
+               for (i = 0; i < num; i++) {
                        if (kill (procs[i].num, opt_signal) != -1) continue;
                        if (errno==ESRCH) continue; // gone now, which is OK
                        fprintf (stderr, "pkill: %ld - %s\n",
@@ -625,5 +625,5 @@ main (int argc, char **argv)
                else
                        output_numlist (procs);
        }
-       return ((procs[0].num) == 0 ? 1 : 0);
+       return !num;
 }
index e3245c1b3ca089e520d23c2f8ff803c545386a87..4fad11db4344295596a2ab17b8a1614ef450c113 100644 (file)
@@ -37,6 +37,17 @@ extern void __cyg_profile_func_enter(void*,void*);
 #define LEAVE(x)
 #endif
 
+// convert hex string to unsigned long long
+static unsigned long long unhex(const char *restrict cp){
+    unsigned long long ull = 0;
+    for(;;){
+        char c = *cp++;
+        if(unlikely(c<0x30)) break;
+        ull = (ull<<4) | (c - (c>0x57) ? 0x57 : 0x30) ;
+    }
+    return ull;
+}
+
 static int task_dir_missing;
 
 ///////////////////////////////////////////////////////////////////////////
@@ -71,7 +82,6 @@ typedef struct status_table_struct {
 // must be padded out to 64 entries, maybe 128 in the future.
 
 static void status2proc(char *S, proc_t *restrict P, int is_proc){
-    char ShdPnd[16] = "";
     long Threads = 0;
     long Tgid = 0;
     long Pid = 0;
@@ -147,6 +157,7 @@ ENTER(0x220);
     P->vm_exe  = 0;
     P->vm_lib  = 0;
     P->nlwp    = 0;
+    P->signal[0] = '\0';  // so we can detect it as missing for very old kernels
 
     goto base;
 
@@ -195,9 +206,10 @@ ENTER(0x220);
         S--;   // put back the '\n' or '\0'
         continue;
     }
+#ifdef SIGNAL_STRING
     case_ShdPnd:
-        memcpy(ShdPnd, S, 16);
-        // we know it to be 16 char, so no '\0' needed
+        memcpy(P->signal, S, 16);
+        P->signal[16] = '\0';
         continue;
     case_SigBlk:
         memcpy(P->blocked, S, 16);
@@ -212,9 +224,26 @@ ENTER(0x220);
         P->sigignore[16] = '\0';
         continue;
     case_SigPnd:
-        memcpy(P->signal, S, 16);
-        P->signal[16] = '\0';
+        memcpy(P->_sigpnd, S, 16);
+        P->_sigpnd[16] = '\0';
         continue;
+#else
+    case_ShdPnd:
+        P->signal = unhex(S);
+        continue;
+    case_SigBlk:
+        P->blocked = unhex(S);
+        continue;
+    case_SigCgt:
+        P->sigcatch = unhex(S);
+        continue;
+    case_SigIgn:
+        P->sigignore = unhex(S);
+        continue;
+    case_SigPnd:
+        P->_sigpnd = unhex(S);
+        continue;
+#endif
     case_State:
         P->state = *S;
         continue;
@@ -265,11 +294,25 @@ ENTER(0x220);
         continue;
     }
 
+#if 0
     // recent kernels supply per-tgid pending signals
     if(is_proc && *ShdPnd){
        memcpy(P->signal, ShdPnd, 16);
        P->signal[16] = '\0';
     }
+#endif
+
+    // recent kernels supply per-tgid pending signals
+#ifdef SIGNAL_STRING
+    if(!is_proc || !P->signal[0]){
+       memcpy(P->signal, P->_sigpnd, 16);
+       P->signal[16] = '\0';
+    }
+#else
+    if(!is_proc || !have_process_pending){
+       P->signal = P->_sigpnd;
+    }
+#endif
 
     // Linux 2.4.13-pre1 to max 2.4.xx have a useless "Tgid"
     // that is not initialized for built-in kernel tasks.
@@ -764,11 +807,17 @@ proc_t* readtask(PROCTAB *restrict const PT, const proc_t *restrict const p, pro
   if(!t) t = xcalloc(t, sizeof *t); /* passed buf or alloced mem */
 
   // 1. got to fake a thread for old kernels
-  // 2. for single-threaded processes, this is faster
+  // 2. for single-threaded processes, this is faster (but must patch up stuff that differs!)
   if(task_dir_missing || p->nlwp < 2){
     if(PT->did_fake) goto out;
     PT->did_fake=1;
     memcpy(t,p,sizeof(proc_t));
+    // use the per-task pending, not per-tgid pending
+#ifdef SIGNAL_STRING
+       memcpy(&t->signal, &t->_sigpnd, sizeof t->signal);
+#else
+       t->signal = t->_sigpnd;
+#endif
     return t;
   }
 
index ae44c0a183d9d5a1f486d13d388bcb50269e8996..a953b291a8e50a2185324ec23b1193de2894da1f 100644 (file)
@@ -58,17 +58,19 @@ typedef struct proc_t {
 #ifdef SIGNAL_STRING
     char
        // Linux 2.1.7x and up have 64 signals. Allow 64, plus '\0' and padding.
-       signal[18],     // status          mask of pending signals
+       signal[18],     // status          mask of pending signals, per-task for readtask() but per-proc for readproc()
        blocked[18],    // status          mask of blocked signals
        sigignore[18],  // status          mask of ignored signals
-       sigcatch[18];   // status          mask of caught  signals
+       sigcatch[18],   // status          mask of caught  signals
+       _sigpnd[18];    // status          mask of PER TASK pending signals
 #else
     long long
        // Linux 2.1.7x and up have 64 signals.
-       signal,         // status          mask of pending signals
+       signal,         // status          mask of pending signals, per-task for readtask() but per-proc for readproc()
        blocked,        // status          mask of blocked signals
        sigignore,      // status          mask of ignored signals
-       sigcatch;       // status          mask of caught  signals
+       sigcatch,       // status          mask of caught  signals
+       _sigpnd;        // status          mask of PER TASK pending signals
 #endif
     unsigned KLONG
        start_code,     // stat            address of beginning of code segment