blob: 8a99e0f9e99d016044a8c85974a91d3a787ee5e2 [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersenc4996011999-10-20 22:08:37 +00002/*
3 * Mini kill implementation for busybox
4 *
5 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23
Eric Andersencc8ed391999-10-05 16:24:54 +000024#include "internal.h"
25#include <stdio.h>
26#include <stdlib.h>
Erik Andersen246cc6d2000-03-07 07:41:42 +000027#include <errno.h>
Eric Andersencc8ed391999-10-05 16:24:54 +000028#include <unistd.h>
29#include <signal.h>
Eric Andersena7093171999-10-23 05:42:08 +000030#include <ctype.h>
Eric Andersenabc0f4f1999-12-08 23:19:36 +000031#include <sys/stat.h>
32#include <unistd.h>
Eric Andersencc8ed391999-10-05 16:24:54 +000033
Erik Andersene49d5ec2000-02-08 19:58:47 +000034static const char *kill_usage =
35 "kill [-signal] process-id [process-id ...]\n\n"
36 "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
37 "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
Eric Andersenabc0f4f1999-12-08 23:19:36 +000038
Erik Andersen246cc6d2000-03-07 07:41:42 +000039static const char *killall_usage =
40 "killall [-signal] process-name [process-name ...]\n\n"
41 "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
42 "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
43
44
45#define KILL 0
46#define KILLALL 1
Eric Andersencc8ed391999-10-05 16:24:54 +000047
48struct signal_name {
Erik Andersene49d5ec2000-02-08 19:58:47 +000049 const char *name;
50 int number;
Eric Andersencc8ed391999-10-05 16:24:54 +000051};
52
53const struct signal_name signames[] = {
Erik Andersene49d5ec2000-02-08 19:58:47 +000054 {"HUP", SIGHUP},
55 {"INT", SIGINT},
56 {"QUIT", SIGQUIT},
57 {"ILL", SIGILL},
58 {"TRAP", SIGTRAP},
59 {"ABRT", SIGABRT},
Eric Andersencc8ed391999-10-05 16:24:54 +000060#ifndef __alpha__
Erik Andersene49d5ec2000-02-08 19:58:47 +000061 {"IOT", SIGIOT},
Eric Andersencc8ed391999-10-05 16:24:54 +000062#endif
Eric Andersene77ae3a1999-10-19 20:03:34 +000063#if defined(__sparc__) || defined(__alpha__)
Erik Andersene49d5ec2000-02-08 19:58:47 +000064 {"EMT", SIGEMT},
Eric Andersencc8ed391999-10-05 16:24:54 +000065#else
Erik Andersene49d5ec2000-02-08 19:58:47 +000066 {"BUS", SIGBUS},
Eric Andersencc8ed391999-10-05 16:24:54 +000067#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +000068 {"FPE", SIGFPE},
69 {"KILL", SIGKILL},
Eric Andersene77ae3a1999-10-19 20:03:34 +000070#if defined(__sparc__) || defined(__alpha__)
Erik Andersene49d5ec2000-02-08 19:58:47 +000071 {"BUS", SIGBUS},
Eric Andersencc8ed391999-10-05 16:24:54 +000072#else
Erik Andersene49d5ec2000-02-08 19:58:47 +000073 {"USR1", SIGUSR1},
Eric Andersencc8ed391999-10-05 16:24:54 +000074#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +000075 {"SEGV", SIGSEGV},
Eric Andersene77ae3a1999-10-19 20:03:34 +000076#if defined(__sparc__) || defined(__alpha__)
Erik Andersene49d5ec2000-02-08 19:58:47 +000077 {"SYS", SIGSYS},
Eric Andersencc8ed391999-10-05 16:24:54 +000078#else
Erik Andersene49d5ec2000-02-08 19:58:47 +000079 {"USR2", SIGUSR2},
Eric Andersencc8ed391999-10-05 16:24:54 +000080#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +000081 {"PIPE", SIGPIPE},
82 {"ALRM", SIGALRM},
83 {"TERM", SIGTERM},
Eric Andersene77ae3a1999-10-19 20:03:34 +000084#if defined(__sparc__) || defined(__alpha__)
Erik Andersene49d5ec2000-02-08 19:58:47 +000085 {"URG", SIGURG},
86 {"STOP", SIGSTOP},
87 {"TSTP", SIGTSTP},
88 {"CONT", SIGCONT},
89 {"CHLD", SIGCHLD},
90 {"TTIN", SIGTTIN},
91 {"TTOU", SIGTTOU},
92 {"IO", SIGIO},
Eric Andersencc8ed391999-10-05 16:24:54 +000093# ifndef __alpha__
Erik Andersene49d5ec2000-02-08 19:58:47 +000094 {"POLL", SIGIO},
Eric Andersencc8ed391999-10-05 16:24:54 +000095# endif
Erik Andersene49d5ec2000-02-08 19:58:47 +000096 {"XCPU", SIGXCPU},
97 {"XFSZ", SIGXFSZ},
98 {"VTALRM", SIGVTALRM},
99 {"PROF", SIGPROF},
100 {"WINCH", SIGWINCH},
Eric Andersencc8ed391999-10-05 16:24:54 +0000101# ifdef __alpha__
Erik Andersene49d5ec2000-02-08 19:58:47 +0000102 {"INFO", SIGINFO},
Eric Andersencc8ed391999-10-05 16:24:54 +0000103# else
Erik Andersene49d5ec2000-02-08 19:58:47 +0000104 {"LOST", SIGLOST},
Eric Andersencc8ed391999-10-05 16:24:54 +0000105# endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000106 {"USR1", SIGUSR1},
107 {"USR2", SIGUSR2},
Eric Andersencc8ed391999-10-05 16:24:54 +0000108#else
Erik Andersene49d5ec2000-02-08 19:58:47 +0000109 {"STKFLT", SIGSTKFLT},
110 {"CHLD", SIGCHLD},
111 {"CONT", SIGCONT},
112 {"STOP", SIGSTOP},
113 {"TSTP", SIGTSTP},
114 {"TTIN", SIGTTIN},
115 {"TTOU", SIGTTOU},
116 {"URG", SIGURG},
117 {"XCPU", SIGXCPU},
118 {"XFSZ", SIGXFSZ},
119 {"VTALRM", SIGVTALRM},
120 {"PROF", SIGPROF},
121 {"WINCH", SIGWINCH},
122 {"IO", SIGIO},
123 {"POLL", SIGPOLL},
124 {"PWR", SIGPWR},
125 {"UNUSED", SIGUNUSED},
Eric Andersencc8ed391999-10-05 16:24:54 +0000126#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000127 {0, 0}
Eric Andersencc8ed391999-10-05 16:24:54 +0000128};
129
Erik Andersene49d5ec2000-02-08 19:58:47 +0000130extern int kill_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +0000131{
Erik Andersen246cc6d2000-03-07 07:41:42 +0000132 int whichApp, sig = SIGTERM;
133 const char *appUsage;
134
135 /* Figure out what we are trying to do here */
136 whichApp = (strcmp(*argv, "killall") == 0)?
137 KILLALL : KILL;
138 appUsage = (whichApp == KILLALL)? killall_usage : kill_usage;
Eric Andersencc8ed391999-10-05 16:24:54 +0000139
Eric Andersenabc0f4f1999-12-08 23:19:36 +0000140 argc--;
141 argv++;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000142 /* Parse any options */
143 if (argc < 1)
Erik Andersen246cc6d2000-03-07 07:41:42 +0000144 usage(appUsage);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000145
146 while (argc > 0 && **argv == '-') {
147 while (*++(*argv)) {
148 switch (**argv) {
149 case 'l':
150 {
151 int col = 0;
152 const struct signal_name *s = signames;
153
154 while (s->name != 0) {
155 col +=
156 fprintf(stderr, "%2d) %-8s", s->number,
157 (s++)->name);
158 if (col > 60) {
159 fprintf(stderr, "\n");
160 col = 0;
161 }
162 }
163 fprintf(stderr, "\n\n");
164 exit(TRUE);
165 }
166 break;
167 case '-':
Erik Andersen246cc6d2000-03-07 07:41:42 +0000168 usage(appUsage);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000169 default:
170 {
171 if (isdigit(**argv)) {
172 sig = atoi(*argv);
173 if (sig < 0 || sig >= NSIG)
174 goto end;
175 else {
176 argc--;
177 argv++;
178 goto do_it_now;
179 }
180 } else {
181 const struct signal_name *s = signames;
182
183 while (s->name != 0) {
184 if (strcasecmp(s->name, *argv) == 0) {
185 sig = s->number;
186 argc--;
187 argv++;
188 goto do_it_now;
189 }
190 s++;
191 }
192 if (s->name == 0)
193 goto end;
194 }
195 }
196 }
197 argc--;
198 argv++;
199 }
Eric Andersencc8ed391999-10-05 16:24:54 +0000200 }
Eric Andersen3cf52d11999-10-12 22:26:06 +0000201
Erik Andersene49d5ec2000-02-08 19:58:47 +0000202 do_it_now:
Eric Andersenabc0f4f1999-12-08 23:19:36 +0000203
Erik Andersen246cc6d2000-03-07 07:41:42 +0000204 if (whichApp == KILL) {
205 /* Looks like they want to do a kill. Do that */
206 while (--argc >= 0) {
207 int pid;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000208
Erik Andersen246cc6d2000-03-07 07:41:42 +0000209 if (!isdigit(**argv))
210 fatalError( "Bad PID: %s\n", strerror(errno));
211 pid = strtol(*argv, NULL, 0);
212 if (kill(pid, sig) != 0)
213 fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
214 argv++;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000215 }
Erik Andersen246cc6d2000-03-07 07:41:42 +0000216 } else {
217 /* Looks like they want to do a killall. Do that */
218 while (--argc >= 0) {
219 int pid;
220
221 while((pid = findPidByName( *argv))) {
222 if (kill(pid, sig) != 0)
223 fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
224 }
225 argv++;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000226 }
Eric Andersen3cf52d11999-10-12 22:26:06 +0000227 }
Erik Andersen246cc6d2000-03-07 07:41:42 +0000228
Erik Andersene49d5ec2000-02-08 19:58:47 +0000229 exit(TRUE);
Eric Andersenabc0f4f1999-12-08 23:19:36 +0000230
Eric Andersena7093171999-10-23 05:42:08 +0000231
Erik Andersene49d5ec2000-02-08 19:58:47 +0000232 end:
Erik Andersen246cc6d2000-03-07 07:41:42 +0000233 fatalError( "bad signal name: %s\n", *argv);
Eric Andersencc8ed391999-10-05 16:24:54 +0000234}