Mercurial > hg > toybox
comparison toys/killall.c @ 475:1fb149e75ebf
Add killall by Andreas Heck, and factor out common pid code to lib.h.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sat, 18 Feb 2012 15:12:41 -0600 |
parents | |
children | f0b07ce5f125 |
comparison
equal
deleted
inserted
replaced
474:d76583999029 | 475:1fb149e75ebf |
---|---|
1 /* vi: set sw=4 ts=4: | |
2 * | |
3 * killall.c - Send a signal (default: TERM) to all processes with the given names. | |
4 * | |
5 * Copyright 2012 Andreas Heck <aheck@gmx.de> | |
6 * | |
7 * Not in SUSv4. | |
8 * See http://opengroup.org/onlinepubs/9699919799/utilities/ | |
9 | |
10 USE_KILLALL(NEWTOY(killall, "?lq", TOYFLAG_USR|TOYFLAG_BIN)) | |
11 | |
12 config KILLALL | |
13 bool "killall" | |
14 default y | |
15 help | |
16 usage: killall [-l] [-q] [-SIG] PROCESS_NAME... | |
17 | |
18 Send a signal (default: TERM) to all processes with the given names. | |
19 | |
20 -l print list of all available signals | |
21 -q don't print any warnings or error messages | |
22 */ | |
23 | |
24 #include "toys.h" | |
25 | |
26 #define FLAG_q 1 | |
27 #define FLAG_l 2 | |
28 | |
29 DEFINE_GLOBALS( | |
30 int matched; | |
31 int signum; | |
32 ) | |
33 #define TT this.killall | |
34 | |
35 struct signame { | |
36 int num; | |
37 const char *name; | |
38 }; | |
39 | |
40 static struct signame signames[] = { | |
41 #ifdef SIGHUP | |
42 {SIGHUP, "HUP"}, | |
43 #endif | |
44 #ifdef SIGINT | |
45 {SIGINT, "INT"}, | |
46 #endif | |
47 #ifdef SIGQUIT | |
48 {SIGQUIT, "QUIT"}, | |
49 #endif | |
50 #ifdef SIGILL | |
51 {SIGILL, "ILL"}, | |
52 #endif | |
53 #ifdef SIGTRAP | |
54 {SIGTRAP, "TRAP"}, | |
55 #endif | |
56 #ifdef SIGTABRT | |
57 {SIGABRT, "ABRT"}, | |
58 #endif | |
59 #ifdef SIGTABRT | |
60 {SIGIOT, "IOT"}, | |
61 #endif | |
62 #ifdef SIGBUS | |
63 {SIGBUS, "BUS"}, | |
64 #endif | |
65 #ifdef SIGFPE | |
66 {SIGFPE, "FPE"}, | |
67 #endif | |
68 #ifdef SIGKILL | |
69 {SIGKILL, "KILL"}, | |
70 #endif | |
71 #ifdef SIGUSR1 | |
72 {SIGUSR1, "USR1"}, | |
73 #endif | |
74 #ifdef SIGSEGV | |
75 {SIGSEGV, "SEGV"}, | |
76 #endif | |
77 #ifdef SIGUSR2 | |
78 {SIGUSR2, "USR2"}, | |
79 #endif | |
80 #ifdef SIGPIPE | |
81 {SIGPIPE, "PIPE"}, | |
82 #endif | |
83 #ifdef SIGALRM | |
84 {SIGALRM, "ALRM"}, | |
85 #endif | |
86 #ifdef SIGTERM | |
87 {SIGTERM, "TERM"}, | |
88 #endif | |
89 #ifdef SIGSTKFLT | |
90 {SIGSTKFLT, "STKFLT"}, | |
91 #endif | |
92 #ifdef SIGCHLD | |
93 {SIGCHLD, "CHLD"}, | |
94 #endif | |
95 #ifdef SIGCONT | |
96 {SIGCONT, "CONT"}, | |
97 #endif | |
98 #ifdef SIGSTOP | |
99 {SIGSTOP, "STOP"}, | |
100 #endif | |
101 #ifdef SIGSTOP | |
102 {SIGSTOP, "STOP"}, | |
103 #endif | |
104 #ifdef SIGTSTP | |
105 {SIGTSTP, "TSTP"}, | |
106 #endif | |
107 #ifdef SIGTTIN | |
108 {SIGTTIN, "TTIN"}, | |
109 #endif | |
110 #ifdef SIGTTOU | |
111 {SIGTTOU, "TTOU"}, | |
112 #endif | |
113 #ifdef SIGURG | |
114 {SIGURG, "URG"}, | |
115 #endif | |
116 #ifdef SIGXCPU | |
117 {SIGXCPU, "XCPU"}, | |
118 #endif | |
119 #ifdef SIGXFSZ | |
120 {SIGXFSZ, "XFSZ"}, | |
121 #endif | |
122 #ifdef SIGVTALRM | |
123 {SIGVTALRM, "VTALRM"}, | |
124 #endif | |
125 #ifdef SIGVTALRM | |
126 {SIGVTALRM, "VTALRM"}, | |
127 #endif | |
128 #ifdef SIGPROF | |
129 {SIGPROF, "PROF"}, | |
130 #endif | |
131 #ifdef SIGWINCH | |
132 {SIGWINCH, "WINCH"}, | |
133 #endif | |
134 #ifdef SIGIO | |
135 {SIGIO, "IO"}, | |
136 #endif | |
137 #ifdef SIGPOLL | |
138 {SIGPOLL, "POLL"}, | |
139 #endif | |
140 #ifdef SIGPWR | |
141 {SIGPWR, "PWR"}, | |
142 #endif | |
143 #ifdef SIGSYS | |
144 {SIGSYS, "SYS"}, | |
145 #endif | |
146 #ifdef SIGUNUSED | |
147 {SIGUNUSED, "UNUSED"}, | |
148 #endif | |
149 {0, NULL} | |
150 }; | |
151 | |
152 static int sig_to_num(const char *pidstr) { | |
153 int i, num; | |
154 | |
155 if (isdigit(pidstr[0])) { | |
156 num = atoi(pidstr); | |
157 | |
158 return num; | |
159 } | |
160 | |
161 for (i = 0; signames[i].num; i++) { | |
162 if (strcmp(pidstr, signames[i].name) == 0) { | |
163 return signames[i].num; | |
164 } | |
165 } | |
166 | |
167 return -1; | |
168 } | |
169 | |
170 static void print_signals() { | |
171 int i; | |
172 | |
173 for (i = 0; signames[i].num; i++) { | |
174 puts(signames[i].name); | |
175 } | |
176 } | |
177 | |
178 static void kill_process(const char *pidstr) { | |
179 int ret; | |
180 pid_t pid = atoi(pidstr); | |
181 | |
182 TT.matched = 1; | |
183 ret = kill(pid, TT.signum); | |
184 | |
185 if (ret == -1) { | |
186 if (toys.optflags & FLAG_q) perror("kill"); | |
187 } | |
188 } | |
189 | |
190 void killall_main(void) | |
191 { | |
192 char **names; | |
193 | |
194 TT.matched = 0; | |
195 TT.signum = SIGTERM; | |
196 | |
197 if (toys.optflags & FLAG_l) { | |
198 print_signals(); | |
199 exit(0); | |
200 } | |
201 | |
202 if (!*toys.optargs) { | |
203 toys.exithelp = 1; | |
204 error_exit("Process name missing!"); | |
205 } | |
206 | |
207 names = toys.optargs; | |
208 | |
209 if ((*toys.optargs)[0] == '-') { | |
210 TT.signum = sig_to_num(&(*toys.optargs)[1]); | |
211 if (TT.signum <= 0) { | |
212 if (toys.optflags & FLAG_q) fprintf(stderr, "Invalid signal\n"); | |
213 exit(1); | |
214 } | |
215 names = ++toys.optargs; | |
216 } | |
217 | |
218 if (!*names) { | |
219 toys.exithelp = 1; | |
220 error_exit("Process name missing!"); | |
221 } | |
222 | |
223 for_each_pid_with_name_in(names, kill_process); | |
224 | |
225 if (!TT.matched) { | |
226 if (!(toys.optflags & FLAG_q)) fprintf(stderr, "No such process\n"); | |
227 exit(1); | |
228 } | |
229 } |