Some #include updates.
[oweals/busybox.git] / procps / 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 <unistd.h>
32
33 #define KILL    0
34 #define KILLALL 1
35
36 struct signal_name {
37         const char *name;
38         int number;
39 };
40
41 const struct signal_name signames[] = {
42         /* Everything, order not important */
43         {"HUP", SIGHUP},
44         {"INT", SIGINT},
45         {"QUIT", SIGQUIT},
46         {"ILL", SIGILL},
47         {"TRAP", SIGTRAP},
48         {"ABRT", SIGABRT},
49         {"FPE", SIGFPE},
50         {"KILL", SIGKILL},
51         {"SEGV", SIGSEGV},
52         {"PIPE", SIGPIPE},
53         {"ALRM", SIGALRM},
54         {"TERM", SIGTERM},
55         {"BUS", SIGBUS},
56         {"USR1", SIGUSR1},
57         {"USR2", SIGUSR2},
58         {"STOP", SIGSTOP},
59         {"CONT", SIGCONT},
60         {"TTIN", SIGTTIN},
61         {"TTOU", SIGTTOU},
62         {"IO", SIGIO},
63         {"TSTP", SIGTSTP},
64         {"CHLD", SIGCHLD},
65         {"XCPU", SIGXCPU},
66         {"XFSZ", SIGXFSZ},
67         {"PROF", SIGPROF},
68         {"WINCH", SIGWINCH},
69         {"URG", SIGURG},
70         {"VTALRM", SIGVTALRM},
71 #ifndef __alpha__
72         /* everything except alpha */
73         {"IOT", SIGIOT},
74         {"POLL", SIGPOLL},
75 #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},
96         {"PWR", SIGPWR},
97         {"UNUSED", SIGUNUSED},
98 #endif
99         {0, 0}
100 };
101
102 extern int kill_main(int argc, char **argv)
103 {
104         int whichApp, sig = SIGTERM;
105         const char *appUsage;
106
107 #ifdef BB_KILLALL
108         /* Figure out what we are trying to do here */
109         whichApp = (strcmp(applet_name, "killall") == 0)? KILLALL : KILL; 
110         appUsage = (whichApp == KILLALL)?  killall_usage : kill_usage;
111 #else
112         whichApp = KILL;
113         appUsage = kill_usage;
114 #endif
115
116         argc--;
117         argv++;
118         /* Parse any options */
119         if (argc < 1)
120                 usage(appUsage);
121
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 '-':
144                                 usage(appUsage);
145                         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                 }
176         }
177
178   do_it_now:
179
180         if (whichApp == KILL) {
181                 /* Looks like they want to do a kill. Do that */
182                 while (--argc >= 0) {
183                         int pid;
184
185                         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++;
191                 }
192         } 
193 #ifdef BB_KILLALL
194         else {
195                 int all_found = TRUE;
196                 pid_t myPid=getpid();
197                 /* Looks like they want to do a killall.  Do that */
198                 while (--argc >= 0) {
199                         pid_t* pidList;
200
201                         pidList = findPidByName( *argv);
202                         if (!pidList) {
203                                 all_found = FALSE;
204                                 errorMsg( "%s: no process killed\n", *argv);
205                         }
206
207                         for(; pidList && *pidList!=0; pidList++) {
208                                 if (*pidList==myPid)
209                                         continue;
210                                 if (kill(*pidList, sig) != 0) 
211                                         fatalError( "Could not kill pid '%d': %s\n", *pidList, strerror(errno));
212                         }
213                         /* 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 */
216                         argv++;
217                 }
218                 exit (all_found);
219         }
220 #endif
221
222         exit(TRUE);
223
224
225   end:
226         fatalError( "bad signal name: %s\n", *argv);
227 }