changeset 477:f0b07ce5f125

Cleanups to pidof (including some global infrastructure shared with killall).
author Rob Landley <rob@landley.net>
date Sat, 18 Feb 2012 18:09:14 -0600
parents d10b58563cff
children 7f292460d268
files lib/lib.c toys/killall.c toys/pidof.c
diffstat 3 files changed, 38 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/lib/lib.c	Sat Feb 18 15:19:00 2012 -0600
+++ b/lib/lib.c	Sat Feb 18 18:09:14 2012 -0600
@@ -811,56 +811,34 @@
 }
 
 // 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;
-
-        if (pathpos + strlen(entry->d_name) + 1 > PATH_LEN) continue;
+        int fd;
 
-        strcpy(&path[pathpos], entry->d_name);
-        pathpos += strlen(entry->d_name);
+        if (!isdigit(*entry->d_name)) continue;
 
-        if (pathpos + strlen("/cmdline") + 1 > PATH_LEN) continue;
-        strcpy(&path[pathpos], "/cmdline");
+        if (sizeof(path) <= snprintf(path, sizeof(path), "/proc/%s/cmdline", 
+            entry->d_name)) continue;
 
-        fp = fopen(path, "r");
-        if (!fp) {
-            perror("fopen");
-            continue;
-        }
+        if (-1 != (fd=xopen(path, O_RDONLY))) {
+            int n = read(fd, cmd, sizeof(cmd));
 
-        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
 }
--- a/toys/killall.c	Sat Feb 18 15:19:00 2012 -0600
+++ b/toys/killall.c	Sat Feb 18 18:09:14 2012 -0600
@@ -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 @@
 #define FLAG_l	2
 
 DEFINE_GLOBALS(
-		int matched;
-		int signum;
+	int matched;
+	int signum;
 )
 #define TT this.killall
 
@@ -149,7 +148,8 @@
 	{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 @@
 	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 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 @@
 
 	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) {
--- a/toys/pidof.c	Sat Feb 18 15:19:00 2012 -0600
+++ b/toys/pidof.c	Sat Feb 18 18:09:14 2012 -0600
@@ -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 @@
 
 #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');
 }