killall.c revision ff9ee8fc15e1a41bffe06bfcee30368e7c117601
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
10USE_KILLALL(NEWTOY(killall, "?lq", TOYFLAG_USR|TOYFLAG_BIN))
11
12config 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
29DEFINE_GLOBALS(
30		int matched;
31		int signum;
32)
33#define TT this.killall
34
35struct signame {
36	int num;
37	const char *name;
38};
39
40static 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
152static 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
170static void print_signals() {
171	int i;
172
173	for (i = 0; signames[i].num; i++) {
174		puts(signames[i].name);
175	}
176}
177
178static 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
190void 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}
230