blob: dc48d4337cdfc781c867a1149dbb131bb6bac974 [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/*
Erik Andersen5661fe02000-04-05 01:00:52 +00003 * Mini kill/killall implementation for busybox
Eric Andersenc4996011999-10-20 22:08:37 +00004 *
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 <unistd.h>
Eric Andersencc8ed391999-10-05 16:24:54 +000032
Erik Andersen246cc6d2000-03-07 07:41:42 +000033#define KILL 0
34#define KILLALL 1
Eric Andersencc8ed391999-10-05 16:24:54 +000035
36struct signal_name {
Erik Andersene49d5ec2000-02-08 19:58:47 +000037 const char *name;
38 int number;
Eric Andersencc8ed391999-10-05 16:24:54 +000039};
40
41const struct signal_name signames[] = {
Eric Andersen3cfa9ec2000-07-06 17:05:33 +000042 /* Everything, order not important */
Erik Andersene49d5ec2000-02-08 19:58:47 +000043 {"HUP", SIGHUP},
44 {"INT", SIGINT},
45 {"QUIT", SIGQUIT},
46 {"ILL", SIGILL},
47 {"TRAP", SIGTRAP},
48 {"ABRT", SIGABRT},
Erik Andersene49d5ec2000-02-08 19:58:47 +000049 {"FPE", SIGFPE},
50 {"KILL", SIGKILL},
Erik Andersene49d5ec2000-02-08 19:58:47 +000051 {"SEGV", SIGSEGV},
Erik Andersene49d5ec2000-02-08 19:58:47 +000052 {"PIPE", SIGPIPE},
53 {"ALRM", SIGALRM},
54 {"TERM", SIGTERM},
Eric Andersen3cfa9ec2000-07-06 17:05:33 +000055 {"BUS", SIGBUS},
Erik Andersene49d5ec2000-02-08 19:58:47 +000056 {"USR1", SIGUSR1},
57 {"USR2", SIGUSR2},
Erik Andersene49d5ec2000-02-08 19:58:47 +000058 {"STOP", SIGSTOP},
Eric Andersen3cfa9ec2000-07-06 17:05:33 +000059 {"CONT", SIGCONT},
Erik Andersene49d5ec2000-02-08 19:58:47 +000060 {"TTIN", SIGTTIN},
61 {"TTOU", SIGTTOU},
Eric Andersen3cfa9ec2000-07-06 17:05:33 +000062 {"IO", SIGIO},
63 {"TSTP", SIGTSTP},
64 {"CHLD", SIGCHLD},
Erik Andersene49d5ec2000-02-08 19:58:47 +000065 {"XCPU", SIGXCPU},
66 {"XFSZ", SIGXFSZ},
Erik Andersene49d5ec2000-02-08 19:58:47 +000067 {"PROF", SIGPROF},
68 {"WINCH", SIGWINCH},
Eric Andersen3cfa9ec2000-07-06 17:05:33 +000069 {"URG", SIGURG},
70 {"VTALRM", SIGVTALRM},
71#ifndef __alpha__
72 /* everything except alpha */
73 {"IOT", SIGIOT},
Erik Andersene49d5ec2000-02-08 19:58:47 +000074 {"POLL", SIGPOLL},
Eric Andersen3cfa9ec2000-07-06 17:05:33 +000075#endif
76#if defined(__sparc__) || defined(__alpha__) || defined(__mips__)
77 /* everthing except intel */
78 {"EMT", SIGEMT},
79 {"SYS", SIGSYS},
80# ifdef __alpha__
81 /* alpha only */
82 {"LOST", SIGLOST},
83#endif
84#ifdef __sparc__
85 /* space only */
86 {"INFO", SIGINFO},
87#endif
88#ifdef __mips__
89 /* mips only */
90 {"CLD", SIGCLD},
91 {"PWR", SIGPWR},
92#endif
93#else
94 /* intel only */
95 {"STKFLT", SIGSTKFLT},
Erik Andersene49d5ec2000-02-08 19:58:47 +000096 {"PWR", SIGPWR},
97 {"UNUSED", SIGUNUSED},
Eric Andersencc8ed391999-10-05 16:24:54 +000098#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +000099 {0, 0}
Eric Andersencc8ed391999-10-05 16:24:54 +0000100};
101
Erik Andersene49d5ec2000-02-08 19:58:47 +0000102extern int kill_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +0000103{
Erik Andersen246cc6d2000-03-07 07:41:42 +0000104 int whichApp, sig = SIGTERM;
105 const char *appUsage;
106
Erik Andersen6273f652000-03-17 01:12:41 +0000107#ifdef BB_KILLALL
Erik Andersen246cc6d2000-03-07 07:41:42 +0000108 /* Figure out what we are trying to do here */
Matt Kraaie58771e2000-07-12 15:38:49 +0000109 whichApp = (strcmp(applet_name, "killall") == 0)? KILLALL : KILL;
Erik Andersen246cc6d2000-03-07 07:41:42 +0000110 appUsage = (whichApp == KILLALL)? killall_usage : kill_usage;
Erik Andersen6273f652000-03-17 01:12:41 +0000111#else
112 whichApp = KILL;
113 appUsage = kill_usage;
114#endif
Eric Andersencc8ed391999-10-05 16:24:54 +0000115
Eric Andersenabc0f4f1999-12-08 23:19:36 +0000116 argc--;
117 argv++;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000118 /* Parse any options */
119 if (argc < 1)
Erik Andersen246cc6d2000-03-07 07:41:42 +0000120 usage(appUsage);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000121
122 while (argc > 0 && **argv == '-') {
123 while (*++(*argv)) {
124 switch (**argv) {
125 case 'l':
126 {
127 int col = 0;
128 const struct signal_name *s = signames;
129
130 while (s->name != 0) {
131 col +=
132 fprintf(stderr, "%2d) %-8s", s->number,
133 (s++)->name);
134 if (col > 60) {
135 fprintf(stderr, "\n");
136 col = 0;
137 }
138 }
139 fprintf(stderr, "\n\n");
140 exit(TRUE);
141 }
142 break;
143 case '-':
Erik Andersen246cc6d2000-03-07 07:41:42 +0000144 usage(appUsage);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000145 default:
146 {
147 if (isdigit(**argv)) {
148 sig = atoi(*argv);
149 if (sig < 0 || sig >= NSIG)
150 goto end;
151 else {
152 argc--;
153 argv++;
154 goto do_it_now;
155 }
156 } else {
157 const struct signal_name *s = signames;
158
159 while (s->name != 0) {
160 if (strcasecmp(s->name, *argv) == 0) {
161 sig = s->number;
162 argc--;
163 argv++;
164 goto do_it_now;
165 }
166 s++;
167 }
168 if (s->name == 0)
169 goto end;
170 }
171 }
172 }
173 argc--;
174 argv++;
175 }
Eric Andersencc8ed391999-10-05 16:24:54 +0000176 }
Eric Andersen3cf52d11999-10-12 22:26:06 +0000177
Erik Andersene49d5ec2000-02-08 19:58:47 +0000178 do_it_now:
Eric Andersenabc0f4f1999-12-08 23:19:36 +0000179
Erik Andersen246cc6d2000-03-07 07:41:42 +0000180 if (whichApp == KILL) {
181 /* Looks like they want to do a kill. Do that */
182 while (--argc >= 0) {
183 int pid;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000184
Erik Andersen246cc6d2000-03-07 07:41:42 +0000185 if (!isdigit(**argv))
186 fatalError( "Bad PID: %s\n", strerror(errno));
187 pid = strtol(*argv, NULL, 0);
188 if (kill(pid, sig) != 0)
189 fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
190 argv++;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000191 }
Erik Andersen6273f652000-03-17 01:12:41 +0000192 }
193#ifdef BB_KILLALL
194 else {
Pavel Roskin700a5ae2000-06-06 18:10:17 +0000195 int all_found = TRUE;
Erik Andersen0a64de92000-04-18 20:00:03 +0000196 pid_t myPid=getpid();
Erik Andersen246cc6d2000-03-07 07:41:42 +0000197 /* Looks like they want to do a killall. Do that */
198 while (--argc >= 0) {
Erik Andersen825aead2000-04-07 06:00:07 +0000199 pid_t* pidList;
Erik Andersen246cc6d2000-03-07 07:41:42 +0000200
Erik Andersen825aead2000-04-07 06:00:07 +0000201 pidList = findPidByName( *argv);
Pavel Roskin700a5ae2000-06-06 18:10:17 +0000202 if (!pidList) {
203 all_found = FALSE;
Eric Andersen86ab8a32000-06-02 03:21:42 +0000204 errorMsg( "%s: no process killed\n", *argv);
Pavel Roskin700a5ae2000-06-06 18:10:17 +0000205 }
Eric Andersen86ab8a32000-06-02 03:21:42 +0000206
Erik Andersen0a64de92000-04-18 20:00:03 +0000207 for(; pidList && *pidList!=0; pidList++) {
208 if (*pidList==myPid)
209 continue;
Erik Andersen825aead2000-04-07 06:00:07 +0000210 if (kill(*pidList, sig) != 0)
211 fatalError( "Could not kill pid '%d': %s\n", *pidList, strerror(errno));
Erik Andersen246cc6d2000-03-07 07:41:42 +0000212 }
Erik Andersen825aead2000-04-07 06:00:07 +0000213 /* Note that we don't bother to free the memory
214 * allocated in findPidByName(). It will be freed
215 * upon exit, so we can save a byte or two */
Erik Andersen246cc6d2000-03-07 07:41:42 +0000216 argv++;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000217 }
Pavel Roskin700a5ae2000-06-06 18:10:17 +0000218 exit (all_found);
Eric Andersen3cf52d11999-10-12 22:26:06 +0000219 }
Erik Andersen6273f652000-03-17 01:12:41 +0000220#endif
Erik Andersen246cc6d2000-03-07 07:41:42 +0000221
Erik Andersene49d5ec2000-02-08 19:58:47 +0000222 exit(TRUE);
Eric Andersenabc0f4f1999-12-08 23:19:36 +0000223
Eric Andersena7093171999-10-23 05:42:08 +0000224
Erik Andersene49d5ec2000-02-08 19:58:47 +0000225 end:
Erik Andersen246cc6d2000-03-07 07:41:42 +0000226 fatalError( "bad signal name: %s\n", *argv);
Eric Andersencc8ed391999-10-05 16:24:54 +0000227}