Factor out common code between killall/kill and move it to lib/lib.c, plus cleanups...
authorRob Landley <rob@landley.net>
Sun, 26 Feb 2012 19:48:00 +0000 (13:48 -0600)
committerRob Landley <rob@landley.net>
Sun, 26 Feb 2012 19:48:00 +0000 (13:48 -0600)
lib/lib.c
lib/lib.h
toys/kill.c
toys/killall.c

index ba6d132..3f04cb6 100644 (file)
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -842,3 +842,54 @@ void for_each_pid_with_name_in(char **names, void (*callback)(pid_t pid))
 
     closedir(dp);
 }
+
+struct signame {
+       int num;
+       char *name;
+};
+
+// Signals required by POSIX 2008:
+// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html
+
+#define SIGNIFY(x) {SIG##x, #x}
+
+static struct signame signames[] = {
+       SIGNIFY(ABRT), SIGNIFY(ALRM), SIGNIFY(BUS), SIGNIFY(CHLD), SIGNIFY(CONT),
+       SIGNIFY(FPE), SIGNIFY(HUP), SIGNIFY(ILL), SIGNIFY(INT), SIGNIFY(KILL),
+       SIGNIFY(PIPE), SIGNIFY(QUIT), SIGNIFY(SEGV), SIGNIFY(STOP), SIGNIFY(TERM),
+       SIGNIFY(TSTP), SIGNIFY(TTIN), SIGNIFY(TTOU), SIGNIFY(USR1), SIGNIFY(USR2),
+       SIGNIFY(SYS), SIGNIFY(TRAP), SIGNIFY(URG), SIGNIFY(VTALRM), SIGNIFY(XCPU),
+       SIGNIFY(XFSZ)
+};
+
+// not in posix: SIGNIFY(STKFLT), SIGNIFY(WINCH), SIGNIFY(IO), SIGNIFY(PWR)
+// obsolete: SIGNIFY(PROF) SIGNIFY(POLL)
+
+// Convert name to signal number.  If name == NULL print names.
+int sig_to_num(char *pidstr)
+{
+       int i;
+
+       if (pidstr) {
+               char *s;
+               i = strtol(pidstr, &s, 10);
+               if (!*s) return i;
+
+               if (!strncasecmp(pidstr, "sig", 3)) pidstr+=3;
+       }
+       for (i = 0; i < sizeof(signames)/sizeof(struct signame); i++)
+               if (!pidstr) xputs(signames[i].name);
+               else if (!strcasecmp(pidstr, signames[i].name))
+                       return signames[i].num;
+
+       return -1;
+}
+
+char *num_to_sig(int sig)
+{
+       int i;
+
+       for (i=0; i<sizeof(signames)/sizeof(struct signame); i++)
+               if (signames[i].num == sig) return signames[i].name;
+       return NULL;
+}
index dd8a3f1..a695973 100644 (file)
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -126,3 +126,8 @@ struct mtab_list {
 struct mtab_list *getmountlist(int die);
 
 void bunzipStream(int src_fd, int dst_fd);
+
+// signal
+
+int sig_to_num(char *pidstr);
+char *num_to_sig(int sig);
index 10c784b..d9beda3 100644 (file)
@@ -6,13 +6,13 @@
  *
  * See http://opengroup.org/onlinepubs/9699919799/utilities/kill.html
 
-USE_KILL(NEWTOY(kill, NULL, TOYFLAG_BIN))
+USE_KILL(NEWTOY(kill, "?s:l", TOYFLAG_BIN))
 
 config KILL
        bool "kill"
        default y
        help
-         usage: kill [-l signal_number | -s signal_name | -signal_name | -signal_number] pid...
+         usage: kill [-l [SIGNAL] | -s SIGNAL | -SIGNAL] pid...
 
          Send a signal to a process
 
@@ -20,167 +20,57 @@ config KILL
 
 #include "toys.h"
 
+DEFINE_GLOBALS(
+       char *signame;
+)
+
 #define TT this.kill
 
-typedef struct {
-       int signum;
-       char *signame;
-} signals_t;
-
-const signals_t signals[] = {
-       { 1, "HUP"},
-       { 2, "INT"},
-       { 3, "QUIT"},
-       { 4, "ILL"},
-       { 5, "TRAP"},
-       { 6, "ABRT"},
-       { 7, "BUS"},
-       { 8, "FPE"},
-       { 9, "KILL"},
-       { 10, "USR1"},
-       { 11, "SEGV"},
-       { 12, "USR2"},
-       { 13, "PIPE"},
-       { 14, "ALRM"},
-       { 15, "TERM"},
-       { 16, "STKFLT"},
-       { 17, "CHLD"},
-       { 18, "CONT"},
-       { 19, "STOP"},
-       { 20, "TSTP"},
-       { 21, "TTIN"},
-       { 22, "TTOU"},
-       { 23, "URG"},
-       { 24, "XCPU"},
-       { 25, "XFSZ"},
-       { 26, "VTALRM"},
-       { 27, "PROF"},
-       { 28, "WINCH"},
-       { 29, "POLL"},
-       { 30, "PWR"},
-       { 31, "SYS"},
-       /* terminator */
-       { -1, NULL},
-};
-
-static char* signum_to_signame(int sig)
+void kill_main(void)
 {
-       int i = 0;
-       for (;;) {
-               if (signals[i].signum == sig)
-                       return signals[i].signame;
+       int signum;
+       char *tmp, **args = toys.optargs;
+       pid_t pid;
 
-               if (signals[++i].signum == -1)
-                       break;
-       }
-       return NULL;
-}
+       // list signal(s)
+       if (toys.optflags & 1) {
+               if (*args) {
+                       int signum = sig_to_num(*args);
+                       char *s = NULL;
 
-static int signame_to_signum(char *signame)
-{
-       int i=0;
-       for (;;) {
-               if (!strcmp(signals[i].signame, signame))
-                       return signals[i].signum;
-               if (signals[++i].signum == -1)
-                       break;
+                       if (signum>=0) s = num_to_sig(signum&127);
+                       puts(s ? s : "UNKNOWN");
+               } else sig_to_num(NULL);
+               return;
        }
-       return -1;
-}
 
-static int send_signal(int sig, pid_t pid)
-{
-       if (kill(pid, sig) < 0) {
-               perror("kill");
-               return -1;
-       }
-       return 0;
-}
+       // signal must come before pids, so "kill -9 -1" isn't confusing.
+printf("*args=%s\n", *args);
 
-static void list_all_signals()
-{
-       int i = 0;
-       for (;;) {
-               printf("%s ", signals[i++].signame);
-               if (i % 16 == 0)
-                       printf("\n");
-               if (signals[i].signum == -1)
-                       break;
-       }
-       printf("\n");
-}
+       if (!TT.signame && *args && **args=='-') TT.signame=*(args++)+1;
+printf("TT.signame=%s\n", TT.signame);
+       if (TT.signame) {
+               char *arg;
+               int i = strtol(TT.signame, &arg, 10);
+               if (!*arg) arg = num_to_sig(i);
+               else arg = TT.signame;
 
-static int list_signal(int signum)
-{
-       char *signam = signum_to_signame(signum);
-       if (signam) {
-               printf("%s\n", signam);
-               return 0;
-       } else {
-               printf("Unknown signal %d\n", signum);
-               return -1;
-       }
-}
+               if (!arg || -1 == (signum = sig_to_num(arg)))
+                       error_exit("Unknown signal '%s'", arg);
+       } else signum = SIGTERM;
 
-static int list_signal_by_name(char *signame)
-{
-       int signum = signame_to_signum(signame);
-       if (signum > 0) {
-               printf("%d\n", signum);
-               return 0;
-       } else {
-               printf("Unknown signal %s\n", signame);
-               return -1;
+       if (!*args) {
+               toys.exithelp++;
+               error_exit("missing argument");
        }
-} 
 
-void kill_main(void)
-{
-       int signum = 0;
-       int have_signal = 0;
-       char *signame, *tmp;
-       pid_t pid;
-       while (*toys.optargs) {
-               char *arg = *(toys.optargs++);
-               if (arg[0] == '-' && !have_signal) {
-                       arg++;
-                       switch(arg[0]) {
-                       case 'l':
-                               if (!*toys.optargs)
-                                       list_all_signals();
-                               else {
-                                       signum = strtol(*(toys.optargs), &signame, 10);
-                                       if (signame == *(toys.optargs))
-                                               list_signal_by_name(signame);
-                                       else
-                                               list_signal(signum);
-                               }
-                               return;
-                       case 's':
-                               arg = *(toys.optargs++);
-                       default:
-                               signum = strtol(arg, &signame, 10);
-                               if (signame == arg) {
-                                       signum = signame_to_signum(signame);
-                                       if (signum < 0) {
-                                               toys.exitval = EXIT_FAILURE;
-                                               return;
-                                       }
-                               }
-                               have_signal = 1;
-                       }
-               } else {
-                       /* pids */
-                       pid = strtol(arg, &tmp, 10);
-                       if (tmp == arg) {
-                               toys.exitval = EXIT_FAILURE;
-                               return;
-                       }
-                       if (send_signal(signum, pid) < 0) {
-                               toys.exitval = EXIT_FAILURE;
-                               return;
-                       }
-                               
+       while (*args) {
+               char *arg = *(args++);
+
+               pid = strtol(arg, &tmp, 10);
+               if (*tmp || kill(pid, signum) < 0) {
+                       error_msg("unknown pid '%s'", arg);
+                       toys.exitval = EXIT_FAILURE;
                }
        }
 }
index 4437983..b4e0694 100644 (file)
@@ -30,44 +30,6 @@ DEFINE_GLOBALS(
 )
 #define TT this.killall
 
-struct signame {
-       int num;
-       char *name;
-};
-
-// Signals required by POSIX 2008:
-// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html
-
-#define SIGNIFY(x) {SIG##x, #x}
-
-static struct signame signames[] = {
-       SIGNIFY(ABRT), SIGNIFY(ALRM), SIGNIFY(BUS), SIGNIFY(CHLD), SIGNIFY(CONT),
-       SIGNIFY(FPE), SIGNIFY(HUP), SIGNIFY(ILL), SIGNIFY(INT), SIGNIFY(KILL),
-       SIGNIFY(PIPE), SIGNIFY(QUIT), SIGNIFY(SEGV), SIGNIFY(STOP), SIGNIFY(TERM),
-       SIGNIFY(TSTP), SIGNIFY(TTIN), SIGNIFY(TTOU), SIGNIFY(USR1), SIGNIFY(USR2),
-       SIGNIFY(SYS), SIGNIFY(TRAP), SIGNIFY(URG), SIGNIFY(VTALRM), SIGNIFY(XCPU),
-       SIGNIFY(XFSZ)
-};
-
-// SIGNIFY(STKFLT), SIGNIFY(WINCH), SIGNIFY(IO), SIGNIFY(PWR)
-
-// Convert name to signal number.  If name == NULL print names.
-static int sig_to_num(char *pidstr)
-{
-       int i;
-
-       if (pidstr) {
-               if (isdigit(*pidstr)) return atol(pidstr);
-               if (!strncasecmp(pidstr, "sig", 3)) pidstr+=3;
-       }
-       for (i = 0; i < sizeof(signames)/sizeof(struct signame); i++)
-               if (!pidstr) xputs(signames[i].name);
-               else if (!strcasecmp(pidstr, signames[i].name))
-                       return signames[i].num;
-
-       return -1;
-}
-
 static void kill_process(pid_t pid)
 {
        int ret;