2 * Copyright (c) 1988, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * oct 5 1994 -- almost entirely re-written to allow for process names.
35 * modifications (c) salvatore valente <svalente@mit.edu>
36 * may be used / modified / distributed under the same terms as the original.
38 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
39 * - added Native Language Support
41 * 1999-11-13 aeb Accept signal numers 128+s.
49 #include <ctype.h> /* for isdigit() */
55 #define SIZE(a) (sizeof(a)/sizeof(a[0]))
62 { "HUP", SIGHUP }, /* 1 */
63 { "INT", SIGINT }, /* 2 */
64 { "QUIT", SIGQUIT }, /* 3 */
65 { "ILL", SIGILL }, /* 4 */
66 { "ABRT", SIGABRT }, /* 6 */
67 { "FPE", SIGFPE }, /* 8 */
68 { "KILL", SIGKILL }, /* 9 */
69 { "SEGV", SIGSEGV }, /* 11 */
70 { "PIPE", SIGPIPE }, /* 13 */
71 { "ALRM", SIGALRM }, /* 14 */
72 { "TERM", SIGTERM }, /* 15 */
73 { "USR1", SIGUSR1 }, /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */
74 { "USR2", SIGUSR2 }, /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */
75 { "CHLD", SIGCHLD }, /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */
76 { "CONT", SIGCONT }, /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */
77 { "STOP", SIGSTOP }, /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */
78 { "TSTP", SIGTSTP }, /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */
79 { "TTIN", SIGTTIN }, /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */
80 { "TTOU", SIGTTOU }, /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */
81 /* Miscellaneous other signals */
83 { "TRAP", SIGTRAP }, /* 5 */
86 { "IOT", SIGIOT }, /* 6, same as SIGABRT */
89 { "EMT", SIGEMT }, /* 7 (mips,alpha,sparc*) */
92 { "BUS", SIGBUS }, /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */
95 { "SYS", SIGSYS }, /* 12 (mips,alpha,sparc*) */
98 { "STKFLT", SIGSTKFLT }, /* 16 (arm,i386,m68k,ppc) */
101 { "URG", SIGURG }, /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */
104 { "IO", SIGIO }, /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */
107 { "POLL", SIGPOLL }, /* same as SIGIO */
110 { "CLD", SIGCLD }, /* same as SIGCHLD (mips) */
113 { "XCPU", SIGXCPU }, /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */
116 { "XFSZ", SIGXFSZ }, /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */
119 { "VTALRM", SIGVTALRM }, /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */
122 { "PROF", SIGPROF }, /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */
125 { "PWR", SIGPWR }, /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */
128 { "INFO", SIGINFO }, /* 29 (alpha) */
131 { "LOST", SIGLOST }, /* 29 (arm,i386,m68k,ppc,sparc*) */
134 { "WINCH", SIGWINCH }, /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */
137 { "UNUSED", SIGUNUSED }, /* 31 (arm,i386,m68k,ppc) */
141 int main (int argc, char *argv[]);
142 extern char *mybasename(char *);
143 int signame_to_signum (char *sig);
144 int arg_to_signum (char *arg, int mask);
145 void nosig (char *name);
146 void printsig (int sig);
147 void printsignals (FILE *fp);
148 int usage (int status);
149 int kill_verbose (char *procname, int pid, int sig);
151 extern int *get_pids (char *, int);
153 static char *progname;
155 int main (int argc, char *argv[])
157 int errors, numsig, pid;
159 int do_pid, do_kill, check_all;
163 if ((p = strrchr(progname, '/')) != NULL)
166 setlocale(LC_ALL, "");
167 bindtextdomain(PACKAGE, LOCALEDIR);
171 do_pid = (! strcmp (progname, "pid")); /* Yecch */
175 /* loop through the arguments.
176 actually, -a is the only option can be used with other options.
177 `kill' is basically a one-option-at-most program. */
178 for (argc--, argv++; argc > 0; argc--, argv++) {
183 if (! strcmp (arg, "--")) {
187 if (! strcmp (arg, "-v") || ! strcmp (arg, "-V") ||
188 ! strcmp (arg, "--version")) {
189 printf(_("%s from %s\n"), progname, PACKAGE_STRING);
192 if (! strcmp (arg, "-a")) {
196 if (! strcmp (arg, "-l")) {
198 printsignals (stdout);
204 /* argc == 2, accept "kill -l $?" */
206 if ((numsig = arg_to_signum (arg, 1)) < 0) {
207 fprintf (stderr, _("%s: unknown signal %s\n"), progname, arg);
213 if (! strcmp (arg, "-p")) {
219 if (! strcmp (arg, "-s")) {
228 if ((numsig = arg_to_signum (arg, 0)) < 0) {
234 /* `arg' begins with a dash but is not a known option.
235 so it's probably something like -HUP, or -1/-n
237 -n could be signal n, or pid -n (i.e. process group n).
238 In case of doubt POSIX tells us to assume a signal.
239 If a signal has been parsed, assume it's a pid, break */
243 if ((numsig = arg_to_signum (arg, 0)) < 0) {
259 /* we're done with the options.
260 the rest of the arguments should be process ids and names.
262 for (errors = 0; (arg = *argv) != NULL; argv++) {
263 pid = strtol (arg, &ep, 10);
265 errors += kill_verbose (arg, pid, numsig);
267 pids = get_pids (arg, check_all);
270 fprintf (stderr, _("%s: can't find process \"%s\"\n"),
274 for (ip = pids; *ip >= 0; ip++)
275 errors += kill_verbose (arg, *ip, numsig);
283 int signame_to_signum (char *sig)
287 if (! strncasecmp (sig, "sig", 3))
289 for (n = 0; n < SIZE(sys_signame); n++) {
290 if (! strcasecmp (sys_signame[n].name, sig))
291 return sys_signame[n].val;
296 int arg_to_signum (char *arg, int maskbit)
301 if (isdigit (*arg)) {
302 numsig = strtol (arg, &ep, 10);
303 if (numsig >= NSIG && maskbit && (numsig & 128) != 0)
305 if (*ep != 0 || numsig < 0 || numsig >= NSIG)
309 return (signame_to_signum (arg));
312 void nosig (char *name)
314 fprintf (stderr, _("%s: unknown signal %s; valid signals:\n"), progname, name);
315 printsignals (stderr);
318 void printsig (int sig)
322 for (n = 0; n < SIZE(sys_signame); n++) {
323 if (sys_signame[n].val == sig) {
324 printf ("%s\n", sys_signame[n].name);
331 void printsignals (FILE *fp)
336 for (n = 0; n < SIZE(sys_signame); n++) {
337 lth = 1+strlen(sys_signame[n].name);
344 fputs (sys_signame[n].name, fp);
349 int usage (int status)
353 fp = (status == 0 ? stdout : stderr);
354 fprintf (fp, _("usage: %s [ -s signal | -p ] [ -a ] pid ...\n"), progname);
355 fprintf (fp, _(" %s -l [ signal ]\n"), progname);
359 int kill_verbose (char *procname, int pid, int sig)
362 printf ("%d\n", pid);
365 if (kill (pid, sig) < 0) {
366 fprintf (stderr, "%s ", progname);