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