Oops. Forgot the usleep.c file.
[oweals/busybox.git] / kill.c
1 /* vi: set sw=4 ts=4: */
2 /*
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
24 #include "internal.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <signal.h>
30 #include <ctype.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33
34 static 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";
38
39 #ifdef BB_KILLALL
40 static const char *killall_usage =
41         "killall [-signal] process-name [process-name ...]\n\n"
42         "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
43         "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
44 #endif
45
46 #define KILL    0
47 #define KILLALL 1
48
49 struct signal_name {
50         const char *name;
51         int number;
52 };
53
54 const struct signal_name signames[] = {
55         {"HUP", SIGHUP},
56         {"INT", SIGINT},
57         {"QUIT", SIGQUIT},
58         {"ILL", SIGILL},
59         {"TRAP", SIGTRAP},
60         {"ABRT", SIGABRT},
61 #ifndef __alpha__
62         {"IOT", SIGIOT},
63 #endif
64 #if defined(__sparc__) || defined(__alpha__)
65         {"EMT", SIGEMT},
66 #else
67         {"BUS", SIGBUS},
68 #endif
69         {"FPE", SIGFPE},
70         {"KILL", SIGKILL},
71 #if defined(__sparc__) || defined(__alpha__)
72         {"BUS", SIGBUS},
73 #else
74         {"USR1", SIGUSR1},
75 #endif
76         {"SEGV", SIGSEGV},
77 #if defined(__sparc__) || defined(__alpha__)
78         {"SYS", SIGSYS},
79 #else
80         {"USR2", SIGUSR2},
81 #endif
82         {"PIPE", SIGPIPE},
83         {"ALRM", SIGALRM},
84         {"TERM", SIGTERM},
85 #if defined(__sparc__) || defined(__alpha__)
86         {"URG", SIGURG},
87         {"STOP", SIGSTOP},
88         {"TSTP", SIGTSTP},
89         {"CONT", SIGCONT},
90         {"CHLD", SIGCHLD},
91         {"TTIN", SIGTTIN},
92         {"TTOU", SIGTTOU},
93         {"IO", SIGIO},
94 # ifndef __alpha__
95         {"POLL", SIGIO},
96 # endif
97         {"XCPU", SIGXCPU},
98         {"XFSZ", SIGXFSZ},
99         {"VTALRM", SIGVTALRM},
100         {"PROF", SIGPROF},
101         {"WINCH", SIGWINCH},
102 # ifdef __alpha__
103         {"INFO", SIGINFO},
104 # else
105         {"LOST", SIGLOST},
106 # endif
107         {"USR1", SIGUSR1},
108         {"USR2", SIGUSR2},
109 #else
110         {"STKFLT", SIGSTKFLT},
111         {"CHLD", SIGCHLD},
112         {"CONT", SIGCONT},
113         {"STOP", SIGSTOP},
114         {"TSTP", SIGTSTP},
115         {"TTIN", SIGTTIN},
116         {"TTOU", SIGTTOU},
117         {"URG", SIGURG},
118         {"XCPU", SIGXCPU},
119         {"XFSZ", SIGXFSZ},
120         {"VTALRM", SIGVTALRM},
121         {"PROF", SIGPROF},
122         {"WINCH", SIGWINCH},
123         {"IO", SIGIO},
124         {"POLL", SIGPOLL},
125         {"PWR", SIGPWR},
126         {"UNUSED", SIGUNUSED},
127 #endif
128         {0, 0}
129 };
130
131 extern int kill_main(int argc, char **argv)
132 {
133         int whichApp, sig = SIGTERM;
134         const char *appUsage;
135
136 #ifdef BB_KILLALL
137         /* Figure out what we are trying to do here */
138         whichApp = (strcmp(*argv, "killall") == 0)? 
139                 KILLALL : KILL; 
140         appUsage = (whichApp == KILLALL)?  killall_usage : kill_usage;
141 #else
142         whichApp = KILL;
143         appUsage = kill_usage;
144 #endif
145
146         argc--;
147         argv++;
148         /* Parse any options */
149         if (argc < 1)
150                 usage(appUsage);
151
152         while (argc > 0 && **argv == '-') {
153                 while (*++(*argv)) {
154                         switch (**argv) {
155                         case 'l':
156                                 {
157                                         int col = 0;
158                                         const struct signal_name *s = signames;
159
160                                         while (s->name != 0) {
161                                                 col +=
162                                                         fprintf(stderr, "%2d) %-8s", s->number,
163                                                                         (s++)->name);
164                                                 if (col > 60) {
165                                                         fprintf(stderr, "\n");
166                                                         col = 0;
167                                                 }
168                                         }
169                                         fprintf(stderr, "\n\n");
170                                         exit(TRUE);
171                                 }
172                                 break;
173                         case '-':
174                                 usage(appUsage);
175                         default:
176                                 {
177                                         if (isdigit(**argv)) {
178                                                 sig = atoi(*argv);
179                                                 if (sig < 0 || sig >= NSIG)
180                                                         goto end;
181                                                 else {
182                                                         argc--;
183                                                         argv++;
184                                                         goto do_it_now;
185                                                 }
186                                         } else {
187                                                 const struct signal_name *s = signames;
188
189                                                 while (s->name != 0) {
190                                                         if (strcasecmp(s->name, *argv) == 0) {
191                                                                 sig = s->number;
192                                                                 argc--;
193                                                                 argv++;
194                                                                 goto do_it_now;
195                                                         }
196                                                         s++;
197                                                 }
198                                                 if (s->name == 0)
199                                                         goto end;
200                                         }
201                                 }
202                         }
203                         argc--;
204                         argv++;
205                 }
206         }
207
208   do_it_now:
209
210         if (whichApp == KILL) {
211                 /* Looks like they want to do a kill. Do that */
212                 while (--argc >= 0) {
213                         int pid;
214
215                         if (!isdigit(**argv))
216                                 fatalError( "Bad PID: %s\n", strerror(errno));
217                         pid = strtol(*argv, NULL, 0);
218                         if (kill(pid, sig) != 0) 
219                                 fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
220                         argv++;
221                 }
222         } 
223 #ifdef BB_KILLALL
224         else {
225                 /* Looks like they want to do a killall.  Do that */
226                 while (--argc >= 0) {
227                         int pid;
228
229                         while((pid = findPidByName( *argv))) {
230                                 if (kill(pid, sig) != 0) 
231                                         fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
232                         }
233                         argv++;
234                 }
235         }
236 #endif
237
238         exit(TRUE);
239
240
241   end:
242         fatalError( "bad signal name: %s\n", *argv);
243 }