blob: 51662123213297881e47a9a17fd5407a00a16250 [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>
27#include <unistd.h>
28#include <signal.h>
Eric Andersena7093171999-10-23 05:42:08 +000029#include <ctype.h>
Eric Andersenabc0f4f1999-12-08 23:19:36 +000030#include <sys/stat.h>
31#include <unistd.h>
Eric Andersencc8ed391999-10-05 16:24:54 +000032
Erik Andersene49d5ec2000-02-08 19:58:47 +000033static const char *kill_usage =
34 "kill [-signal] process-id [process-id ...]\n\n"
35 "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
36 "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
Eric Andersenabc0f4f1999-12-08 23:19:36 +000037
Eric Andersencc8ed391999-10-05 16:24:54 +000038
39struct signal_name {
Erik Andersene49d5ec2000-02-08 19:58:47 +000040 const char *name;
41 int number;
Eric Andersencc8ed391999-10-05 16:24:54 +000042};
43
44const struct signal_name signames[] = {
Erik Andersene49d5ec2000-02-08 19:58:47 +000045 {"HUP", SIGHUP},
46 {"INT", SIGINT},
47 {"QUIT", SIGQUIT},
48 {"ILL", SIGILL},
49 {"TRAP", SIGTRAP},
50 {"ABRT", SIGABRT},
Eric Andersencc8ed391999-10-05 16:24:54 +000051#ifndef __alpha__
Erik Andersene49d5ec2000-02-08 19:58:47 +000052 {"IOT", SIGIOT},
Eric Andersencc8ed391999-10-05 16:24:54 +000053#endif
Eric Andersene77ae3a1999-10-19 20:03:34 +000054#if defined(__sparc__) || defined(__alpha__)
Erik Andersene49d5ec2000-02-08 19:58:47 +000055 {"EMT", SIGEMT},
Eric Andersencc8ed391999-10-05 16:24:54 +000056#else
Erik Andersene49d5ec2000-02-08 19:58:47 +000057 {"BUS", SIGBUS},
Eric Andersencc8ed391999-10-05 16:24:54 +000058#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +000059 {"FPE", SIGFPE},
60 {"KILL", SIGKILL},
Eric Andersene77ae3a1999-10-19 20:03:34 +000061#if defined(__sparc__) || defined(__alpha__)
Erik Andersene49d5ec2000-02-08 19:58:47 +000062 {"BUS", SIGBUS},
Eric Andersencc8ed391999-10-05 16:24:54 +000063#else
Erik Andersene49d5ec2000-02-08 19:58:47 +000064 {"USR1", SIGUSR1},
Eric Andersencc8ed391999-10-05 16:24:54 +000065#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +000066 {"SEGV", SIGSEGV},
Eric Andersene77ae3a1999-10-19 20:03:34 +000067#if defined(__sparc__) || defined(__alpha__)
Erik Andersene49d5ec2000-02-08 19:58:47 +000068 {"SYS", SIGSYS},
Eric Andersencc8ed391999-10-05 16:24:54 +000069#else
Erik Andersene49d5ec2000-02-08 19:58:47 +000070 {"USR2", SIGUSR2},
Eric Andersencc8ed391999-10-05 16:24:54 +000071#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +000072 {"PIPE", SIGPIPE},
73 {"ALRM", SIGALRM},
74 {"TERM", SIGTERM},
Eric Andersene77ae3a1999-10-19 20:03:34 +000075#if defined(__sparc__) || defined(__alpha__)
Erik Andersene49d5ec2000-02-08 19:58:47 +000076 {"URG", SIGURG},
77 {"STOP", SIGSTOP},
78 {"TSTP", SIGTSTP},
79 {"CONT", SIGCONT},
80 {"CHLD", SIGCHLD},
81 {"TTIN", SIGTTIN},
82 {"TTOU", SIGTTOU},
83 {"IO", SIGIO},
Eric Andersencc8ed391999-10-05 16:24:54 +000084# ifndef __alpha__
Erik Andersene49d5ec2000-02-08 19:58:47 +000085 {"POLL", SIGIO},
Eric Andersencc8ed391999-10-05 16:24:54 +000086# endif
Erik Andersene49d5ec2000-02-08 19:58:47 +000087 {"XCPU", SIGXCPU},
88 {"XFSZ", SIGXFSZ},
89 {"VTALRM", SIGVTALRM},
90 {"PROF", SIGPROF},
91 {"WINCH", SIGWINCH},
Eric Andersencc8ed391999-10-05 16:24:54 +000092# ifdef __alpha__
Erik Andersene49d5ec2000-02-08 19:58:47 +000093 {"INFO", SIGINFO},
Eric Andersencc8ed391999-10-05 16:24:54 +000094# else
Erik Andersene49d5ec2000-02-08 19:58:47 +000095 {"LOST", SIGLOST},
Eric Andersencc8ed391999-10-05 16:24:54 +000096# endif
Erik Andersene49d5ec2000-02-08 19:58:47 +000097 {"USR1", SIGUSR1},
98 {"USR2", SIGUSR2},
Eric Andersencc8ed391999-10-05 16:24:54 +000099#else
Erik Andersene49d5ec2000-02-08 19:58:47 +0000100 {"STKFLT", SIGSTKFLT},
101 {"CHLD", SIGCHLD},
102 {"CONT", SIGCONT},
103 {"STOP", SIGSTOP},
104 {"TSTP", SIGTSTP},
105 {"TTIN", SIGTTIN},
106 {"TTOU", SIGTTOU},
107 {"URG", SIGURG},
108 {"XCPU", SIGXCPU},
109 {"XFSZ", SIGXFSZ},
110 {"VTALRM", SIGVTALRM},
111 {"PROF", SIGPROF},
112 {"WINCH", SIGWINCH},
113 {"IO", SIGIO},
114 {"POLL", SIGPOLL},
115 {"PWR", SIGPWR},
116 {"UNUSED", SIGUNUSED},
Eric Andersencc8ed391999-10-05 16:24:54 +0000117#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000118 {0, 0}
Eric Andersencc8ed391999-10-05 16:24:54 +0000119};
120
Erik Andersene49d5ec2000-02-08 19:58:47 +0000121extern int kill_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +0000122{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000123 int sig = SIGTERM;
Eric Andersencc8ed391999-10-05 16:24:54 +0000124
Eric Andersenabc0f4f1999-12-08 23:19:36 +0000125 argc--;
126 argv++;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000127 /* Parse any options */
128 if (argc < 1)
129 usage(kill_usage);
130
131 while (argc > 0 && **argv == '-') {
132 while (*++(*argv)) {
133 switch (**argv) {
134 case 'l':
135 {
136 int col = 0;
137 const struct signal_name *s = signames;
138
139 while (s->name != 0) {
140 col +=
141 fprintf(stderr, "%2d) %-8s", s->number,
142 (s++)->name);
143 if (col > 60) {
144 fprintf(stderr, "\n");
145 col = 0;
146 }
147 }
148 fprintf(stderr, "\n\n");
149 exit(TRUE);
150 }
151 break;
152 case '-':
153 usage(kill_usage);
154 default:
155 {
156 if (isdigit(**argv)) {
157 sig = atoi(*argv);
158 if (sig < 0 || sig >= NSIG)
159 goto end;
160 else {
161 argc--;
162 argv++;
163 goto do_it_now;
164 }
165 } else {
166 const struct signal_name *s = signames;
167
168 while (s->name != 0) {
169 if (strcasecmp(s->name, *argv) == 0) {
170 sig = s->number;
171 argc--;
172 argv++;
173 goto do_it_now;
174 }
175 s++;
176 }
177 if (s->name == 0)
178 goto end;
179 }
180 }
181 }
182 argc--;
183 argv++;
184 }
Eric Andersencc8ed391999-10-05 16:24:54 +0000185 }
Eric Andersen3cf52d11999-10-12 22:26:06 +0000186
Erik Andersene49d5ec2000-02-08 19:58:47 +0000187 do_it_now:
Eric Andersenabc0f4f1999-12-08 23:19:36 +0000188
Erik Andersene49d5ec2000-02-08 19:58:47 +0000189 while (--argc >= 0) {
190 int pid;
191 struct stat statbuf;
192 char pidpath[20] = "/proc/";
193
194 if (!isdigit(**argv)) {
195 fprintf(stderr, "bad PID: %s\n", *argv);
196 exit(FALSE);
197 }
198 pid = atoi(*argv);
199 snprintf(pidpath, 20, "/proc/%s/stat", *argv);
200 if (stat(pidpath, &statbuf) != 0) {
201 fprintf(stderr, "kill: (%d) - No such pid\n", pid);
202 exit(FALSE);
203 }
204 fprintf(stderr, "sig = %d\n", sig);
205 if (kill(pid, sig) != 0) {
206 perror(*argv);
207 exit(FALSE);
208 }
209 argv++;
Eric Andersen3cf52d11999-10-12 22:26:06 +0000210 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000211 exit(TRUE);
Eric Andersenabc0f4f1999-12-08 23:19:36 +0000212
Eric Andersena7093171999-10-23 05:42:08 +0000213
Erik Andersene49d5ec2000-02-08 19:58:47 +0000214 end:
215 fprintf(stderr, "bad signal name: %s\n", *argv);
216 exit(TRUE);
Eric Andersencc8ed391999-10-05 16:24:54 +0000217}