Cope with processes owned by someone other than us (for which
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 30 Nov 2012 20:43:58 +0000 (20:43 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 30 Nov 2012 20:43:58 +0000 (20:43 +0000)
/proc/%d/exe won't be readlinkable).

git-svn-id: svn://svn.tartarus.org/sgt/utils@9714 cda61777-01e9-0310-a592-d414129be87e

pid/pid.c

index a43274e..47055d9 100644 (file)
--- a/pid/pid.c
+++ b/pid/pid.c
@@ -247,11 +247,9 @@ static struct pidset get_processes(void)
         }
 
         sprintf(filename, "/proc/%d/exe", pid);
-        if ((exe = get_link_dest(filename)) == NULL) {
-            free(cmdline);
-            free(status);
-            continue;
-        }
+        exe = get_link_dest(filename);
+        /* This may fail, if the process isn't ours, but we continue
+         * anyway. */
 
         /*
          * Now we've got all our raw data out of /proc. Process it
@@ -414,6 +412,18 @@ static int find_command(int pid_argc, const char *const *pid_argv,
     return -1;                         /* no match */
 }
 
+static int strnullcmp(const char *a, const char *b)
+{
+    /*
+     * Like strcmp, but cope with NULL inputs by making them compare
+     * identical to each other and before any non-null string.
+     */
+    if (!a || !b)
+        return (b != 0) - (a != 0);
+    else
+        return strcmp(a, b);
+}
+
 static int argcmp(const char *const *a, const char *const *b)
 {
     while (*a && *b) {
@@ -498,7 +508,7 @@ static struct pidset filter_out_forks(struct pidset in)
         if (pidset_in(&in, proc->ppid)) {
             /* The parent is in our set too. Is it similar? */
             const struct procdata *parent = get_proc(proc->ppid);
-            if (!strcmp(parent->exe, proc->exe) &&
+            if (!strnullcmp(parent->exe, proc->exe) &&
                 !argcmp(parent->argv, proc->argv)) {
                 /* Yes; don't list it. */
                 continue;