killall.c revision 4696bfc4057e87ea8a66bd64aafb9ca14a64290e
1/* vi: set sw=4 ts=4: 2 * 3 * killall.c - Send signal (default: TERM) to all processes with given names. 4 * 5 * Copyright 2012 Andreas Heck <aheck@gmx.de> 6 * 7 * Not in SUSv4. 8 9USE_KILLALL(NEWTOY(killall, "<1?lq", TOYFLAG_USR|TOYFLAG_BIN)) 10 11config KILLALL 12 bool "killall" 13 default y 14 help 15 usage: killall [-l] [-q] [-SIG] PROCESS_NAME... 16 17 Send a signal (default: TERM) to all processes with the given names. 18 19 -l print list of all available signals 20 -q don't print any warnings or error messages 21*/ 22 23#include "toys.h" 24 25#define FLAG_q 1 26#define FLAG_l 2 27 28DEFINE_GLOBALS( 29 int signum; 30) 31#define TT this.killall 32 33struct signame { 34 int num; 35 char *name; 36}; 37 38// Signals required by POSIX 2008: 39// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html 40 41#define SIGNIFY(x) {SIG##x, #x} 42 43static struct signame signames[] = { 44 SIGNIFY(ABRT), SIGNIFY(ALRM), SIGNIFY(BUS), SIGNIFY(CHLD), SIGNIFY(CONT), 45 SIGNIFY(FPE), SIGNIFY(HUP), SIGNIFY(ILL), SIGNIFY(INT), SIGNIFY(KILL), 46 SIGNIFY(PIPE), SIGNIFY(QUIT), SIGNIFY(SEGV), SIGNIFY(STOP), SIGNIFY(TERM), 47 SIGNIFY(TSTP), SIGNIFY(TTIN), SIGNIFY(TTOU), SIGNIFY(USR1), SIGNIFY(USR2), 48 SIGNIFY(SYS), SIGNIFY(TRAP), SIGNIFY(URG), SIGNIFY(VTALRM), SIGNIFY(XCPU), 49 SIGNIFY(XFSZ) 50}; 51 52// SIGNIFY(STKFLT), SIGNIFY(WINCH), SIGNIFY(IO), SIGNIFY(PWR) 53 54// Convert name to signal number. If name == NULL print names. 55static int sig_to_num(char *pidstr) 56{ 57 int i; 58 59 if (pidstr) { 60 if (isdigit(*pidstr)) return atol(pidstr); 61 if (!strncasecmp(pidstr, "sig", 3)) pidstr+=3; 62 } 63 for (i = 0; i < sizeof(signames)/sizeof(struct signame); i++) 64 if (!pidstr) xputs(signames[i].name); 65 else if (!strcasecmp(pidstr, signames[i].name)) 66 return signames[i].num; 67 68 return -1; 69} 70 71static void kill_process(pid_t pid) 72{ 73 int ret; 74 75 toys.exitval = 0; 76 ret = kill(pid, TT.signum); 77 78 if (ret == -1 && !(toys.optflags & FLAG_q)) perror("kill"); 79} 80 81void killall_main(void) 82{ 83 char **names; 84 85 if (toys.optflags & FLAG_l) { 86 sig_to_num(NULL); 87 return; 88 } 89 90 TT.signum = SIGTERM; 91 toys.exitval++; 92 93 if (!*toys.optargs) { 94 toys.exithelp = 1; 95 error_exit("Process name missing!"); 96 } 97 98 names = toys.optargs; 99 100 if (**names == '-') { 101 if (0 > (TT.signum = sig_to_num((*names)+1))) { 102 if (toys.optflags & FLAG_q) exit(1); 103 error_exit("Invalid signal"); 104 } 105 names++; 106 107 if (!*names) { 108 toys.exithelp++; 109 error_exit("Process name missing!"); 110 } 111 } 112 113 for_each_pid_with_name_in(names, kill_process); 114 115 if (toys.exitval && !(toys.optflags & FLAG_q)) 116 error_exit("No such process"); 117} 118