X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=kill.c;h=75277d9626c42b073a65421ac84ed08503ca8ce7;hb=89bc256c9480a137a2286b5b16ff4207e35659e5;hp=00f10f91f364160a8a34bcc71fabb81280d71c95;hpb=b0e9a709ba1ae1724d413a77f5b67b1a3e6c6cb7;p=oweals%2Fbusybox.git diff --git a/kill.c b/kill.c index 00f10f91f..75277d962 100644 --- a/kill.c +++ b/kill.c @@ -1,136 +1,263 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini kill/killall implementation for busybox + * + * Copyright (C) 1995, 1996 by Bruce Perens . + * + * 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 #include +#include #include #include +#include +#include +#include + +static const char *kill_usage = + "kill [-signal] process-id [process-id ...]\n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nSend a signal (default is SIGTERM) to the specified process(es).\n\n" + "Options:\n" "\t-l\tList all signal names and numbers.\n\n" +#endif + ; + +#ifdef BB_KILLALL +static const char *killall_usage = + "killall [-signal] process-name [process-name ...]\n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nSend a signal (default is SIGTERM) to the specified process(es).\n\n" + "Options:\n" "\t-l\tList all signal names and numbers.\n\n" +#endif +#endif + ; -const char kill_usage[] = "kill [-signal] process-id [process-id ...]\n"; +#define KILL 0 +#define KILLALL 1 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 (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) - goto end; - } else { - const struct signal_name *s = signames; - for (;;) { - if (strcmp (s->name, &argv[1][1]) == 0) { - sig = s->number; - break; + int whichApp, sig = SIGTERM; + const char *appUsage; + +#ifdef BB_KILLALL + /* Figure out what we are trying to do here */ + whichApp = (strcmp(*argv, "killall") == 0)? + KILLALL : KILL; + appUsage = (whichApp == KILLALL)? killall_usage : kill_usage; +#else + whichApp = KILL; + appUsage = kill_usage; +#endif + + argc--; + argv++; + /* Parse any options */ + if (argc < 1) + usage(appUsage); + + 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); + } + break; + case '-': + usage(appUsage); + 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; + } + } + } + argc--; + argv++; } - s++; - if (s->name == 0) - goto end; - } } - argv++; - argc--; - } - 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: + + if (whichApp == KILL) { + /* Looks like they want to do a kill. Do that */ + while (--argc >= 0) { + int pid; + + if (!isdigit(**argv)) + fatalError( "Bad PID: %s\n", strerror(errno)); + pid = strtol(*argv, NULL, 0); + if (kill(pid, sig) != 0) + fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno)); + argv++; + } + } +#ifdef BB_KILLALL + else { + int all_found = TRUE; + pid_t myPid=getpid(); + /* Looks like they want to do a killall. Do that */ + while (--argc >= 0) { + pid_t* pidList; + + pidList = findPidByName( *argv); + if (!pidList) { + all_found = FALSE; + errorMsg( "%s: no process killed\n", *argv); + } + + for(; pidList && *pidList!=0; pidList++) { + if (*pidList==myPid) + continue; + if (kill(*pidList, sig) != 0) + fatalError( "Could not kill pid '%d': %s\n", *pidList, strerror(errno)); + } + /* Note that we don't bother to free the memory + * allocated in findPidByName(). It will be freed + * upon exit, so we can save a byte or two */ + argv++; + } + exit (all_found); } - argv++; - argc--; - } - if (had_error) { -end: - usage (kill_usage); - } - exit (TRUE); +#endif + + exit(TRUE); + + + end: + fatalError( "bad signal name: %s\n", *argv); }