Fixed to pass -Wundef
[oweals/busybox.git] / kill.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini kill/killall 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 #define KILL    0
35 #define KILLALL 1
36
37 struct signal_name {
38         const char *name;
39         int number;
40 };
41
42 const struct signal_name signames[] = {
43         /* Everything, order not important */
44         {"HUP", SIGHUP},
45         {"INT", SIGINT},
46         {"QUIT", SIGQUIT},
47         {"ILL", SIGILL},
48         {"TRAP", SIGTRAP},
49         {"ABRT", SIGABRT},
50         {"FPE", SIGFPE},
51         {"KILL", SIGKILL},
52         {"SEGV", SIGSEGV},
53         {"PIPE", SIGPIPE},
54         {"ALRM", SIGALRM},
55         {"TERM", SIGTERM},
56         {"BUS", SIGBUS},
57         {"USR1", SIGUSR1},
58         {"USR2", SIGUSR2},
59         {"STOP", SIGSTOP},
60         {"CONT", SIGCONT},
61         {"TTIN", SIGTTIN},
62         {"TTOU", SIGTTOU},
63         {"IO", SIGIO},
64         {"TSTP", SIGTSTP},
65         {"CHLD", SIGCHLD},
66         {"XCPU", SIGXCPU},
67         {"XFSZ", SIGXFSZ},
68         {"PROF", SIGPROF},
69         {"WINCH", SIGWINCH},
70         {"URG", SIGURG},
71         {"VTALRM", SIGVTALRM},
72 #ifndef __alpha__
73         /* everything except alpha */
74         {"IOT", SIGIOT},
75         {"POLL", SIGPOLL},
76 #endif
77 #if defined(__sparc__) || defined(__alpha__) || defined(__mips__)
78         /* everthing except intel */
79         {"EMT", SIGEMT},
80         {"SYS", SIGSYS},
81 # ifdef __alpha__
82                 /* alpha only */
83                 {"LOST", SIGLOST},
84 #endif
85 #ifdef __sparc__
86                 /* space only */
87                 {"INFO", SIGINFO},
88 #endif
89 #ifdef __mips__
90                 /* mips only */
91                 {"CLD", SIGCLD},
92                 {"PWR", SIGPWR},
93 #endif
94 #else
95         /* intel only */
96         {"STKFLT", SIGSTKFLT},
97         {"PWR", SIGPWR},
98         {"UNUSED", SIGUNUSED},
99 #endif
100         {0, 0}
101 };
102
103 extern int kill_main(int argc, char **argv)
104 {
105         int whichApp, sig = SIGTERM;
106         const char *appUsage;
107
108 #ifdef BB_KILLALL
109         /* Figure out what we are trying to do here */
110         whichApp = (strcmp(applet_name, "killall") == 0)? KILLALL : KILL; 
111         appUsage = (whichApp == KILLALL)?  killall_usage : kill_usage;
112 #else
113         whichApp = KILL;
114         appUsage = kill_usage;
115 #endif
116
117         argc--;
118         argv++;
119         /* Parse any options */
120         if (argc < 1)
121                 usage(appUsage);
122
123         while (argc > 0 && **argv == '-') {
124                 while (*++(*argv)) {
125                         switch (**argv) {
126                         case 'l':
127                                 {
128                                         int col = 0;
129                                         const struct signal_name *s = signames;
130
131                                         while (s->name != 0) {
132                                                 col +=
133                                                         fprintf(stderr, "%2d) %-8s", s->number,
134                                                                         (s++)->name);
135                                                 if (col > 60) {
136                                                         fprintf(stderr, "\n");
137                                                         col = 0;
138                                                 }
139                                         }
140                                         fprintf(stderr, "\n\n");
141                                         exit(TRUE);
142                                 }
143                                 break;
144                         case '-':
145                                 usage(appUsage);
146                         default:
147                                 {
148                                         if (isdigit(**argv)) {
149                                                 sig = atoi(*argv);
150                                                 if (sig < 0 || sig >= NSIG)
151                                                         goto end;
152                                                 else {
153                                                         argc--;
154                                                         argv++;
155                                                         goto do_it_now;
156                                                 }
157                                         } else {
158                                                 const struct signal_name *s = signames;
159
160                                                 while (s->name != 0) {
161                                                         if (strcasecmp(s->name, *argv) == 0) {
162                                                                 sig = s->number;
163                                                                 argc--;
164                                                                 argv++;
165                                                                 goto do_it_now;
166                                                         }
167                                                         s++;
168                                                 }
169                                                 if (s->name == 0)
170                                                         goto end;
171                                         }
172                                 }
173                         }
174                         argc--;
175                         argv++;
176                 }
177         }
178
179   do_it_now:
180
181         if (whichApp == KILL) {
182                 /* Looks like they want to do a kill. Do that */
183                 while (--argc >= 0) {
184                         int pid;
185
186                         if (!isdigit(**argv))
187                                 fatalError( "Bad PID: %s\n", strerror(errno));
188                         pid = strtol(*argv, NULL, 0);
189                         if (kill(pid, sig) != 0) 
190                                 fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
191                         argv++;
192                 }
193         } 
194 #ifdef BB_KILLALL
195         else {
196                 int all_found = TRUE;
197                 pid_t myPid=getpid();
198                 /* Looks like they want to do a killall.  Do that */
199                 while (--argc >= 0) {
200                         pid_t* pidList;
201
202                         pidList = findPidByName( *argv);
203                         if (!pidList) {
204                                 all_found = FALSE;
205                                 errorMsg( "%s: no process killed\n", *argv);
206                         }
207
208                         for(; pidList && *pidList!=0; pidList++) {
209                                 if (*pidList==myPid)
210                                         continue;
211                                 if (kill(*pidList, sig) != 0) 
212                                         fatalError( "Could not kill pid '%d': %s\n", *pidList, strerror(errno));
213                         }
214                         /* Note that we don't bother to free the memory
215                          * allocated in findPidByName().  It will be freed
216                          * upon exit, so we can save a byte or two */
217                         argv++;
218                 }
219                 exit (all_found);
220         }
221 #endif
222
223         exit(TRUE);
224
225
226   end:
227         fatalError( "bad signal name: %s\n", *argv);
228 }