implemented numeric sort (sort -g)
[oweals/busybox.git] / kill.c
diff --git a/kill.c b/kill.c
index da025fafc963f1099ff8ee9ffa35bd16da664a8a..0ba6d76cef4e04424e7ce61488feb67278248774 100644 (file)
--- a/kill.c
+++ b/kill.c
+/*
+ * Mini kill implementation for busybox
+ *
+ * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
 #include "internal.h"
 #include <stdio.h>
 #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;
-       int                             number;
+    const char *name;
+    int number;
 };
 
 const struct signal_name signames[] = {
-       { "HUP",        SIGHUP },
-       { "INT",        SIGINT },
-       { "QUIT",       SIGQUIT },
-       { "ILL",        SIGILL },
-       { "TRAP",       SIGTRAP },
-       { "ABRT",       SIGABRT },
+    {"HUP", SIGHUP},
+    {"INT", SIGINT},
+    {"QUIT", SIGQUIT},
+    {"ILL", SIGILL},
+    {"TRAP", SIGTRAP},
+    {"ABRT", SIGABRT},
 #ifndef __alpha__
-       { "IOT",        SIGIOT },
+    {"IOT", SIGIOT},
 #endif
-#if defined(sparc) || defined(__alpha__)
-       { "EMT",        SIGEMT },
+#if defined(__sparc__) || defined(__alpha__)
+    {"EMT", SIGEMT},
 #else
-       { "BUS",        SIGBUS },
+    {"BUS", SIGBUS},
 #endif
-       { "FPE",        SIGFPE },
-       { "KILL",       SIGKILL },
-#if defined(sparc) || defined(__alpha__)
-       { "BUS",        SIGBUS },
+    {"FPE", SIGFPE},
+    {"KILL", SIGKILL},
+#if defined(__sparc__) || defined(__alpha__)
+    {"BUS", SIGBUS},
 #else
-       { "USR1",       SIGUSR1 },
+    {"USR1", SIGUSR1},
 #endif
-       { "SEGV",       SIGSEGV },
-#if defined(sparc) || defined(__alpha__)
-       { "SYS",        SIGSYS },
+    {"SEGV", SIGSEGV},
+#if defined(__sparc__) || defined(__alpha__)
+    {"SYS", SIGSYS},
 #else
-       { "USR2",       SIGUSR2 },
+    {"USR2", SIGUSR2},
 #endif
-       { "PIPE",       SIGPIPE },
-       { "ALRM",       SIGALRM },
-       { "TERM",       SIGTERM },
-#if defined(sparc) || defined(__alpha__)
-       { "URG",        SIGURG },
-       { "STOP",       SIGSTOP },
-       { "TSTP",       SIGTSTP },
-       { "CONT",       SIGCONT },
-       { "CHLD",       SIGCHLD },
-       { "TTIN",       SIGTTIN },
-       { "TTOU",       SIGTTOU },
-       { "IO",         SIGIO },
+    {"PIPE", SIGPIPE},
+    {"ALRM", SIGALRM},
+    {"TERM", SIGTERM},
+#if defined(__sparc__) || defined(__alpha__)
+    {"URG", SIGURG},
+    {"STOP", SIGSTOP},
+    {"TSTP", SIGTSTP},
+    {"CONT", SIGCONT},
+    {"CHLD", SIGCHLD},
+    {"TTIN", SIGTTIN},
+    {"TTOU", SIGTTOU},
+    {"IO", SIGIO},
 # ifndef __alpha__
-       { "POLL",       SIGIO },
+    {"POLL", SIGIO},
 # endif
-       { "XCPU",       SIGXCPU },
-       { "XFSZ",       SIGXFSZ },
-       { "VTALRM",     SIGVTALRM },
-       { "PROF",       SIGPROF },
-       { "WINCH",      SIGWINCH },
+    {"XCPU", SIGXCPU},
+    {"XFSZ", SIGXFSZ},
+    {"VTALRM", SIGVTALRM},
+    {"PROF", SIGPROF},
+    {"WINCH", SIGWINCH},
 # ifdef __alpha__
-       { "INFO",       SIGINFO },
+    {"INFO", SIGINFO},
 # else
-       { "LOST",       SIGLOST },
+    {"LOST", SIGLOST},
 # endif
-       { "USR1",       SIGUSR1 },
-       { "USR2",       SIGUSR2 },
+    {"USR1", SIGUSR1},
+    {"USR2", SIGUSR2},
 #else
-       { "STKFLT",     SIGSTKFLT },
-       { "CHLD",       SIGCHLD },
-       { "CONT",       SIGCONT },
-       { "STOP",       SIGSTOP },
-       { "TSTP",       SIGTSTP },
-       { "TTIN",       SIGTTIN },
-       { "TTOU",       SIGTTOU },
-       { "URG",        SIGURG },
-       { "XCPU",       SIGXCPU },
-       { "XFSZ",       SIGXFSZ },
-       { "VTALRM",     SIGVTALRM },
-       { "PROF",       SIGPROF },
-       { "WINCH",      SIGWINCH },
-       { "IO",         SIGIO },
-       { "POLL",       SIGPOLL },
-       { "PWR",        SIGPWR },
-       { "UNUSED",     SIGUNUSED },
+    {"STKFLT", SIGSTKFLT},
+    {"CHLD", SIGCHLD},
+    {"CONT", SIGCONT},
+    {"STOP", SIGSTOP},
+    {"TSTP", SIGTSTP},
+    {"TTIN", SIGTTIN},
+    {"TTOU", SIGTTOU},
+    {"URG", SIGURG},
+    {"XCPU", SIGXCPU},
+    {"XFSZ", SIGXFSZ},
+    {"VTALRM", SIGVTALRM},
+    {"PROF", SIGPROF},
+    {"WINCH", SIGWINCH},
+    {"IO", SIGIO},
+    {"POLL", SIGPOLL},
+    {"PWR", SIGPWR},
+    {"UNUSED", SIGUNUSED},
 #endif
-       { 0,            0               }
+    {0, 0}
 };
 
-extern int
-kill_main(struct FileInfo * i, int argc, char * * argv)
+extern int kill_main (int argc, char **argv)
 {
-       int     had_error = 0;
-       int     sig = SIGTERM;
-       if ( argv[1][0] == '-' ) {
-               if ( argv[1][1] >= '0' && argv[1][1] <= '9' ) {
-                       sig = atoi(&argv[1][1]);
-                       if ( sig < 0 || sig >= NSIG ) {
-                               usage(kill_usage);
-                               exit(-1);
+    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;
+
+                   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);
                }
-               else {
-                       const struct signal_name *      s = signames;
-                       for ( ; ; ) {
-                               if ( strcmp(s->name, &argv[1][1]) == 0 ) {
-                                       sig = s->number;
-                                       break;
-                               }
-                               s++;
-                               if ( s->name == 0 ) {
-                                       usage(kill_usage);
-                                       exit(-1);
-                               }
+               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;
+                   }
                }
-               argv++;
-               argc--;
-
+           }
+       argc--;
+       argv++;
        }
-       while ( argc > 1 ) {
-               int     pid;
-               if ( argv[1][0] < '0' || argv[1][0] > '9' ) {
-                       usage(kill_usage);
-                       exit(-1);
-               }
-               pid = atoi(argv[1]);
-               if ( kill(pid, sig) != 0 ) {
-                       had_error = 1;
-                       perror(argv[1]);
-               }
-               argv++;
-               argc--;
+    }
+
+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 ( had_error )
-               return -1;
-       else
-               return 0;
+        if (kill (pid, sig) != 0) {
+            perror (*argv);
+            exit ( FALSE);
+        }
+       argv++;
+    }
+    exit ( TRUE);
+
+
+end:
+    fprintf(stderr, "bad signal name: %s\n", *argv);
+    exit (TRUE);
 }
+
+