Home | History | Annotate | Download | only in lsb
      1 /* killall.c - Send signal (default: TERM) to all processes with given names.
      2  *
      3  * Copyright 2012 Andreas Heck <aheck (at) gmx.de>
      4  *
      5  * http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/killall.html
      6 
      7 USE_KILLALL(NEWTOY(killall, "?s:lqvi", TOYFLAG_USR|TOYFLAG_BIN))
      8 
      9 config KILLALL
     10   bool "killall"
     11   default y
     12   help
     13     usage: killall [-l] [-iqv] [-SIGNAL|-s SIGNAL] PROCESS_NAME...
     14 
     15     Send a signal (default: TERM) to all processes with the given names.
     16 
     17     -i	ask for confirmation before killing
     18     -l	print list of all available signals
     19     -q	don't print any warnings or error messages
     20     -s	send SIGNAL instead of SIGTERM
     21     -v	report if the signal was successfully sent
     22 */
     23 
     24 #define FOR_killall
     25 #include "toys.h"
     26 
     27 GLOBALS(
     28   char *sig;
     29 
     30   int signum;
     31   pid_t cur_pid;
     32   char **names;
     33   short *err;
     34 )
     35 
     36 static int kill_process(pid_t pid, char *name)
     37 {
     38   int offset = 0;
     39 
     40   if (pid == TT.cur_pid) return 0;
     41 
     42   if (toys.optflags & FLAG_i) {
     43     fprintf(stderr, "Signal %s(%d)", name, (int)pid);
     44     if (!yesno(0)) return 0;
     45   }
     46 
     47   errno = 0;
     48   kill(pid, TT.signum);
     49   for (;;) {
     50     if (TT.names[offset] == name) {
     51       TT.err[offset] = errno;
     52       break;
     53     } else offset++;
     54   }
     55   if (errno) {
     56     if (!(toys.optflags & FLAG_q)) perror_msg("pid %d", (int)pid);
     57   } else if (toys.optflags & FLAG_v)
     58     printf("Killed %s(%d) with signal %d\n", name, pid, TT.signum);
     59 
     60   return 0;
     61 }
     62 
     63 void killall_main(void)
     64 {
     65   int i;
     66 
     67   TT.names = toys.optargs;
     68   TT.signum = SIGTERM;
     69 
     70   if (toys.optflags & FLAG_l) {
     71     sig_to_num(NULL);
     72     return;
     73   }
     74 
     75   if (TT.sig || (*TT.names && **TT.names == '-')) {
     76     if (0 > (TT.signum = sig_to_num(TT.sig ? TT.sig : (*TT.names)+1))) {
     77       if (toys.optflags & FLAG_q) exit(1);
     78       error_exit("Invalid signal");
     79     }
     80     if (!TT.sig) {
     81       TT.names++;
     82       toys.optc--;
     83     }
     84   }
     85 
     86   if (!(toys.optflags & FLAG_l) && !toys.optc) help_exit("no name");
     87 
     88   TT.cur_pid = getpid();
     89 
     90   TT.err = xmalloc(2*toys.optc);
     91   for (i=0; i<toys.optc; i++) TT.err[i] = ESRCH;
     92   names_to_pid(TT.names, kill_process);
     93   for (i=0; i<toys.optc; i++) {
     94     if (TT.err[i]) {
     95       toys.exitval = 1;
     96       errno = TT.err[i];
     97       perror_msg_raw(TT.names[i]);
     98     }
     99   }
    100   if (CFG_TOYBOX_FREE) free(TT.err);
    101 }
    102