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 }