X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=procps%2Fkill.c;h=22bb98a120d4c014970626906c8f472706483149;hb=75a5684793da59f8ed4c7fc6b05bc2bf148d06b1;hp=0ba6d76cef4e04424e7ce61488feb67278248774;hpb=abc0f4f8f97b36f2865986374405d091cefea107;p=oweals%2Fbusybox.git diff --git a/procps/kill.c b/procps/kill.c index 0ba6d76ce..22bb98a12 100644 --- a/procps/kill.c +++ b/procps/kill.c @@ -1,7 +1,9 @@ +/* vi: set sw=4 ts=4: */ /* - * Mini kill implementation for busybox + * Mini kill/killall implementation for busybox * * Copyright (C) 1995, 1996 by Bruce Perens . + * Copyright (C) 1999-2003 by Erik Andersen * * 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 @@ -20,196 +22,132 @@ */ -#include "internal.h" #include #include +#include #include #include #include -#include +#include #include +#include "busybox.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"; - - -struct signal_name { - const char *name; - int number; -}; - -const struct signal_name signames[] = { - {"HUP", SIGHUP}, - {"INT", SIGINT}, - {"QUIT", SIGQUIT}, - {"ILL", SIGILL}, - {"TRAP", SIGTRAP}, - {"ABRT", SIGABRT}, -#ifndef __alpha__ - {"IOT", SIGIOT}, -#endif -#if defined(__sparc__) || defined(__alpha__) - {"EMT", SIGEMT}, -#else - {"BUS", SIGBUS}, -#endif - {"FPE", SIGFPE}, - {"KILL", SIGKILL}, -#if defined(__sparc__) || defined(__alpha__) - {"BUS", SIGBUS}, -#else - {"USR1", SIGUSR1}, -#endif - {"SEGV", SIGSEGV}, -#if defined(__sparc__) || defined(__alpha__) - {"SYS", SIGSYS}, -#else - {"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}, -# ifndef __alpha__ - {"POLL", SIGIO}, -# endif - {"XCPU", SIGXCPU}, - {"XFSZ", SIGXFSZ}, - {"VTALRM", SIGVTALRM}, - {"PROF", SIGPROF}, - {"WINCH", SIGWINCH}, -# ifdef __alpha__ - {"INFO", SIGINFO}, -# else - {"LOST", SIGLOST}, -# endif - {"USR1", SIGUSR1}, - {"USR2", SIGUSR2}, +#define KILL 0 +#define KILLALL 1 + +extern int kill_main(int argc, char **argv) +{ + int whichApp, signo = SIGTERM, quiet = 0; + const char *name; + int errors = 0; + +#ifdef CONFIG_KILLALL + /* Figure out what we are trying to do here */ + whichApp = (strcmp(bb_applet_name, "killall") == 0)? KILLALL : KILL; #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}, + whichApp = KILL; #endif - {0, 0} -}; -extern int kill_main (int argc, char **argv) -{ - 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); - } - 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; + /* Parse any options */ + if (argc < 2) + bb_show_usage(); + + if(argv[1][0] != '-'){ + argv++; + argc--; + goto do_it_now; + } + + /* The -l option, which prints out signal names. */ + if(argv[1][1]=='l' && argv[1][2]=='\0'){ + if(argc==2) { + /* Print the whole signal list */ + int col = 0; + for(signo=1; signo < NSIG; signo++) { + name = u_signal_names(0, &signo, 1); + if(name==NULL) /* unnamed */ + continue; + col += printf("%2d) %-16s", signo, name); + if (col > 60) { + printf("\n"); + col = 0; + } } - } - 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++; + printf("\n"); + + } else { + for(argv++; *argv; argv++) { + name = u_signal_names(*argv, &signo, -1); + if(name!=NULL) + printf("%s\n", name); } - if (s->name == 0) - goto end; - } } - } - argc--; - argv++; + /* If they specified -l, were all done */ + return EXIT_SUCCESS; + } + + /* The -q quiet option */ + if(argv[1][1]=='q' && argv[1][2]=='\0'){ + quiet++; + argv++; + argc--; + if(argc<2 || argv[1][0] != '-'){ + goto do_it_now; + } } - } + + if(!u_signal_names(argv[1]+1, &signo, 0)) + bb_error_msg_and_die( "bad signal name '%s'", argv[1]+1); + argv+=2; + argc-=2; 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 (whichApp == KILL) { + /* Looks like they want to do a kill. Do that */ + while (--argc >= 0) { + int pid; + + if (!isdigit(**argv)) + bb_error_msg_and_die( "Bad PID '%s'", *argv); + pid = strtol(*argv, NULL, 0); + if (kill(pid, signo) != 0) { + bb_perror_msg( "Could not kill pid '%d'", pid); + errors++; + } + argv++; + } + } - if (kill (pid, sig) != 0) { - perror (*argv); - exit ( FALSE); - } - argv++; - } - exit ( TRUE); - - -end: - fprintf(stderr, "bad signal name: %s\n", *argv); - exit (TRUE); -} +#ifdef CONFIG_KILLALL + else { + pid_t myPid=getpid(); + /* Looks like they want to do a killall. Do that */ + while (--argc >= 0) { + long* pidList; + pidList = find_pid_by_name(*argv); + if (!pidList || *pidList<=0) { + errors++; + if (quiet==0) + bb_error_msg( "%s: no process killed", *argv); + } else { + long *pl; + for(pl = pidList; *pl !=0 ; pl++) { + if (*pl==myPid) + continue; + if (kill(*pl, signo) != 0) { + errors++; + if (quiet==0) + bb_perror_msg( "Could not kill pid '%ld'", *pl); + } + } + } + free(pidList); + argv++; + } + } +#endif + return errors; +}