implemented numeric sort (sort -g)
[oweals/busybox.git] / kill.c
diff --git a/kill.c b/kill.c
index 2fabf56d2c37c0788c477b6c7ef27376eeddee5f..0ba6d76cef4e04424e7ce61488feb67278248774 100644 (file)
--- a/kill.c
+++ b/kill.c
 #include <stdlib.h>
 #include <unistd.h>
 #include <signal.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+static const char* kill_usage = "kill [-signal] process-id [process-id ...]\n\n"
+"Send a signal (default is SIGTERM) to the specified process(es).\n\n"
+"Options:\n"
+"\t-l\tList all signal names and numbers.\n\n";
 
-const char kill_usage[] = "kill [-signal] process-id [process-id ...]\n";
 
 struct signal_name {
     const char *name;
@@ -112,47 +119,97 @@ const struct signal_name signames[] = {
 
 extern int kill_main (int argc, char **argv)
 {
-    int had_error = 0;
     int sig = SIGTERM;
+    
+    argc--;
+    argv++;
+    /* Parse any options */
+    if (argc < 1) 
+       usage(kill_usage);
 
+    while (argc > 0 && **argv == '-') {
+       while (*++(*argv)) {
+           switch (**argv) {
+           case 'l': 
+               {
+                   int col=0;
+                   const struct signal_name *s = signames;
 
-
-    if (argv[1][0] == '-') {
-       if (argv[1][1] >= '0' && argv[1][1] <= '9') {
-           sig = atoi (&argv[1][1]);
-           if (sig < 0 || sig >= NSIG)
-               goto end;
-       } else {
-           const struct signal_name *s = signames;
-           for (;;) {
-               if (strcmp (s->name, &argv[1][1]) == 0) {
-                   sig = s->number;
-                   break;
+                   while (s->name != 0) {
+                       col+=fprintf(stderr, "%2d) %-8s", s->number, (s++)->name);
+                       if (col>60) {
+                           fprintf(stderr, "\n");
+                           col=0;
+                       }
+                   }
+                   fprintf(stderr, "\n\n");
+                   exit( TRUE);
+               }
+               break;
+           case '-':
+               usage(kill_usage);
+           default:
+               {
+                   if (isdigit( **argv)) {
+                       sig = atoi (*argv);
+                       if (sig < 0 || sig >= NSIG)
+                           goto end;
+                       else {
+                           argc--;
+                           argv++;
+                           goto do_it_now;
+                       }
+                   }
+                   else {
+                       const struct signal_name *s = signames;
+                       while (s->name != 0) {
+                           if (strcasecmp (s->name, *argv) == 0) {
+                               sig = s->number;
+                               argc--;
+                               argv++;
+                               goto do_it_now;
+                           }
+                           s++;
+                       }
+                       if (s->name == 0)
+                           goto end;
+                   }
                }
-               s++;
-               if (s->name == 0)
-                   goto end;
            }
-       }
-       argv++;
        argc--;
-
+       argv++;
+       }
     }
-    while (argc > 1) {
-       int pid;
-       if (argv[1][0] < '0' || argv[1][0] > '9')
-           goto end;
-       pid = atoi (argv[1]);
-       if (kill (pid, sig) != 0) {
-           had_error = 1;
-           perror (argv[1]);
+
+do_it_now:
+
+    while (argc >= 1) {
+        int pid;
+       struct stat statbuf;
+       char pidpath[20]="/proc/";
+       
+        if (! isdigit( **argv)) {
+            fprintf(stderr, "bad PID: %s\n", *argv);
+            exit( FALSE);
+        }
+        pid = atoi (*argv);
+       snprintf(pidpath, 20, "/proc/%s/stat", *argv);
+       if (stat( pidpath, &statbuf)!=0) {
+            fprintf(stderr, "kill: (%d) - No such pid\n", pid);
+            exit( FALSE);
        }
+        if (kill (pid, sig) != 0) {
+            perror (*argv);
+            exit ( FALSE);
+        }
        argv++;
-       argc--;
     }
-    if (had_error) {
+    exit ( TRUE);
+
+
 end:
-       usage (kill_usage);
-    }
+    fprintf(stderr, "bad signal name: %s\n", *argv);
     exit (TRUE);
 }
+
+