Cleanups to pidof (including some global infrastructure shared with killall).
authorRob Landley <rob@landley.net>
Sun, 19 Feb 2012 00:09:14 +0000 (18:09 -0600)
committerRob Landley <rob@landley.net>
Sun, 19 Feb 2012 00:09:14 +0000 (18:09 -0600)
lib/lib.c
toys/killall.c
toys/pidof.c

index 8cc85a9..2c4361a 100644 (file)
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -811,56 +811,34 @@ int yesno(int def)
 }
 
 // Execute a callback for each PID that matches a process name from a list.
-int for_each_pid_with_name_in(char **names,
-        void (*callback) (const char *pid)) {
-#define PATH_LEN 64
-
+void for_each_pid_with_name_in(char **names, void (*callback)(pid_t pid))
+{
     DIR *dp;
     struct dirent *entry;
-    FILE *fp;
-    int n, pathpos;
-    char cmd[PATH_MAX];
-    char path[PATH_LEN];
+    char cmd[PATH_MAX], path[64];
     char **curname;
 
-    dp = opendir("/proc");
-    if (!dp) {
-        perror("opendir");
-        return 1;
-    }
+    if (!(dp = opendir("/proc"))) perror_exit("opendir");
 
     while ((entry = readdir(dp))) {
-        if (!isdigit(entry->d_name[0])) continue;
-        strcpy(path, "/proc/");
-        pathpos = 6;
+        int fd;
 
-        if (pathpos + strlen(entry->d_name) + 1 > PATH_LEN) continue;
+        if (!isdigit(*entry->d_name)) continue;
 
-        strcpy(&path[pathpos], entry->d_name);
-        pathpos += strlen(entry->d_name);
+        if (sizeof(path) <= snprintf(path, sizeof(path), "/proc/%s/cmdline", 
+            entry->d_name)) continue;
 
-        if (pathpos + strlen("/cmdline") + 1 > PATH_LEN) continue;
-        strcpy(&path[pathpos], "/cmdline");
+        if (-1 != (fd=xopen(path, O_RDONLY))) {
+            int n = read(fd, cmd, sizeof(cmd));
 
-        fp = fopen(path, "r");
-        if (!fp) {
-            perror("fopen");
-            continue;
-        }
-
-        n = fread(cmd, 1, PATH_MAX, fp); 
-        fclose(fp);
-        if (n == 0) continue;
+            close(fd);
+            if (n<1) continue;
 
-        for (curname = names; *curname; curname++) {
-            if (strcmp(basename(cmd), *curname) == 0) {
-                callback(entry->d_name);
-            }
+            for (curname = names; *curname; curname++)
+                if (!strcmp(basename(cmd), *curname))
+                    callback(atol(entry->d_name));
         }
     }
 
     closedir(dp);
-
-    return 0;
-#undef PATH_LEN
 }
index fb3e8cb..5f18a64 100644 (file)
@@ -1,13 +1,12 @@
 /* vi: set sw=4 ts=4:
  *
- * killall.c - Send a signal (default: TERM) to all processes with the given names.
+ * killall.c - Send signal (default: TERM) to all processes with given names.
  *
  * Copyright 2012 Andreas Heck <aheck@gmx.de>
  *
  * Not in SUSv4.
- * See http://opengroup.org/onlinepubs/9699919799/utilities/
 
-USE_KILLALL(NEWTOY(killall, "?lq", TOYFLAG_USR|TOYFLAG_BIN))
+USE_KILLALL(NEWTOY(killall, "<1?lq", TOYFLAG_USR|TOYFLAG_BIN))
 
 config KILLALL
        bool "killall"
@@ -27,8 +26,8 @@ config KILLALL
 #define FLAG_l 2
 
 DEFINE_GLOBALS(
-               int matched;
-               int signum;
+       int matched;
+       int signum;
 )
 #define TT this.killall
 
@@ -149,7 +148,8 @@ static struct signame signames[] = {
        {0, NULL}
 };
 
-static int sig_to_num(const char *pidstr) {
+static int sig_to_num(const char *pidstr)
+{
        int i, num;
 
        if (isdigit(pidstr[0])) {
@@ -167,7 +167,8 @@ static int sig_to_num(const char *pidstr) {
        return -1;
 }
 
-static void print_signals() {
+static void print_signals()
+{
        int i;
 
        for (i = 0; signames[i].num; i++) {
@@ -175,28 +176,25 @@ static void print_signals() {
        }
 }
 
-static void kill_process(const char *pidstr) {
+static void kill_process(pid_t pid)
+{
        int ret;
-       pid_t pid = atoi(pidstr);
 
        TT.matched = 1;
        ret = kill(pid, TT.signum);
 
-       if (ret == -1) {
-               if (toys.optflags & FLAG_q) perror("kill");
-       }
+       if (ret == -1 && !(toys.optflags & FLAG_q)) perror("kill");
 }
 
 void killall_main(void)
 {
        char **names;
 
-       TT.matched = 0;
        TT.signum = SIGTERM;
 
        if (toys.optflags & FLAG_l) {
                print_signals();
-               exit(0);
+               return;
        }
 
        if (!*toys.optargs) {
@@ -206,13 +204,13 @@ void killall_main(void)
 
        names = toys.optargs;
 
-       if ((*toys.optargs)[0] == '-') {
-               TT.signum = sig_to_num(&(*toys.optargs)[1]);
+       if (**names == '-') {
+               TT.signum = sig_to_num((*names)+1);
                if (TT.signum <= 0) {
-                       if (toys.optflags & FLAG_q) fprintf(stderr, "Invalid signal\n");
+                       if (toys.optflags & FLAG_q) error_exit("Invalid signal");
                        exit(1);
                }
-               names = ++toys.optargs;
+               names++;
        }
 
        if (!*names) {
index 329b008..d8f24be 100644 (file)
@@ -5,9 +5,8 @@
  * Copyright 2012 Andreas Heck <aheck@gmx.de>
  *
  * Not in SUSv4.
- * See http://opengroup.org/onlinepubs/9699919799/utilities/
 
-USE_PIDOF(NEWTOY(pidof, "", TOYFLAG_USR|TOYFLAG_BIN))
+USE_PIDOF(NEWTOY(pidof, "<1", TOYFLAG_USR|TOYFLAG_BIN))
 
 config PIDOF
        bool "pidof"
@@ -20,31 +19,14 @@ config PIDOF
 
 #include "toys.h"
 
-DEFINE_GLOBALS(
-               int matched;
-)
-#define TT this.pidof
-
-
-static void print_pid (const char *pid) {
-    if (TT.matched) putchar(' ');
-    fputs(pid, stdout);
-    TT.matched = 1;
+static void print_pid(pid_t pid) {
+    xprintf("%s%ld", toys.exitval ? "" : " ", (long)pid);
+    toys.exitval = 0;
 }
 
 void pidof_main(void)
 {
-    int err;
-
-       TT.matched = 0;
-
-    if (!toys.optargs) exit(1);
-
-    err = for_each_pid_with_name_in(toys.optargs, print_pid);
-    if (err) exit(1);
-
-    if (!TT.matched)
-        exit(1);
-    else
-        putchar('\n');
+    toys.exitval = 1;
+    for_each_pid_with_name_in(toys.optargs, print_pid);
+    if (!toys.exitval) xputc('\n');
 }