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