fsck_minix.c lost fat.
[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 <unistd.h>
28 #include <signal.h>
29 #include <ctype.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32
33 static 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";
37
38
39 struct signal_name {
40         const char *name;
41         int number;
42 };
43
44 const struct signal_name signames[] = {
45         {"HUP", SIGHUP},
46         {"INT", SIGINT},
47         {"QUIT", SIGQUIT},
48         {"ILL", SIGILL},
49         {"TRAP", SIGTRAP},
50         {"ABRT", SIGABRT},
51 #ifndef __alpha__
52         {"IOT", SIGIOT},
53 #endif
54 #if defined(__sparc__) || defined(__alpha__)
55         {"EMT", SIGEMT},
56 #else
57         {"BUS", SIGBUS},
58 #endif
59         {"FPE", SIGFPE},
60         {"KILL", SIGKILL},
61 #if defined(__sparc__) || defined(__alpha__)
62         {"BUS", SIGBUS},
63 #else
64         {"USR1", SIGUSR1},
65 #endif
66         {"SEGV", SIGSEGV},
67 #if defined(__sparc__) || defined(__alpha__)
68         {"SYS", SIGSYS},
69 #else
70         {"USR2", SIGUSR2},
71 #endif
72         {"PIPE", SIGPIPE},
73         {"ALRM", SIGALRM},
74         {"TERM", SIGTERM},
75 #if defined(__sparc__) || defined(__alpha__)
76         {"URG", SIGURG},
77         {"STOP", SIGSTOP},
78         {"TSTP", SIGTSTP},
79         {"CONT", SIGCONT},
80         {"CHLD", SIGCHLD},
81         {"TTIN", SIGTTIN},
82         {"TTOU", SIGTTOU},
83         {"IO", SIGIO},
84 # ifndef __alpha__
85         {"POLL", SIGIO},
86 # endif
87         {"XCPU", SIGXCPU},
88         {"XFSZ", SIGXFSZ},
89         {"VTALRM", SIGVTALRM},
90         {"PROF", SIGPROF},
91         {"WINCH", SIGWINCH},
92 # ifdef __alpha__
93         {"INFO", SIGINFO},
94 # else
95         {"LOST", SIGLOST},
96 # endif
97         {"USR1", SIGUSR1},
98         {"USR2", SIGUSR2},
99 #else
100         {"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},
117 #endif
118         {0, 0}
119 };
120
121 extern int kill_main(int argc, char **argv)
122 {
123         int sig = SIGTERM;
124
125         argc--;
126         argv++;
127         /* 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                 }
185         }
186
187   do_it_now:
188
189         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++;
210         }
211         exit(TRUE);
212
213
214   end:
215         fprintf(stderr, "bad signal name: %s\n", *argv);
216         exit(TRUE);
217 }