]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - misc-utils/kill.c
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.
48 #include <ctype.h> /* for isdigit() */
55 #include "closestream.h"
63 { "HUP", SIGHUP
}, /* 1 */
64 { "INT", SIGINT
}, /* 2 */
65 { "QUIT", SIGQUIT
}, /* 3 */
66 { "ILL", SIGILL
}, /* 4 */
67 { "ABRT", SIGABRT
}, /* 6 */
68 { "FPE", SIGFPE
}, /* 8 */
69 { "KILL", SIGKILL
}, /* 9 */
70 { "SEGV", SIGSEGV
}, /* 11 */
71 { "PIPE", SIGPIPE
}, /* 13 */
72 { "ALRM", SIGALRM
}, /* 14 */
73 { "TERM", SIGTERM
}, /* 15 */
74 { "USR1", SIGUSR1
}, /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */
75 { "USR2", SIGUSR2
}, /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */
76 { "CHLD", SIGCHLD
}, /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */
77 { "CONT", SIGCONT
}, /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */
78 { "STOP", SIGSTOP
}, /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */
79 { "TSTP", SIGTSTP
}, /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */
80 { "TTIN", SIGTTIN
}, /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */
81 { "TTOU", SIGTTOU
}, /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */
82 /* Miscellaneous other signals */
84 { "TRAP", SIGTRAP
}, /* 5 */
87 { "IOT", SIGIOT
}, /* 6, same as SIGABRT */
90 { "EMT", SIGEMT
}, /* 7 (mips,alpha,sparc*) */
93 { "BUS", SIGBUS
}, /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */
96 { "SYS", SIGSYS
}, /* 12 (mips,alpha,sparc*) */
99 { "STKFLT", SIGSTKFLT
}, /* 16 (arm,i386,m68k,ppc) */
102 { "URG", SIGURG
}, /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */
105 { "IO", SIGIO
}, /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */
108 { "POLL", SIGPOLL
}, /* same as SIGIO */
111 { "CLD", SIGCLD
}, /* same as SIGCHLD (mips) */
114 { "XCPU", SIGXCPU
}, /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */
117 { "XFSZ", SIGXFSZ
}, /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */
120 { "VTALRM", SIGVTALRM
}, /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */
123 { "PROF", SIGPROF
}, /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */
126 { "PWR", SIGPWR
}, /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */
129 { "INFO", SIGINFO
}, /* 29 (alpha) */
132 { "LOST", SIGLOST
}, /* 29 (arm,i386,m68k,ppc,sparc*) */
135 { "WINCH", SIGWINCH
}, /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */
138 { "UNUSED", SIGUNUSED
}, /* 31 (arm,i386,m68k,ppc) */
142 extern char *mybasename(char *);
144 static int arg_to_signum (char *arg
, int mask
);
145 static void nosig (char *name
);
146 static void printsig (int sig
);
147 static void printsignals (FILE *fp
);
148 static int usage (int status
);
149 static int kill_verbose (char *procname
, int pid
, int sig
);
151 static char *progname
;
154 static int use_sigval
;
155 static union sigval sigdata
;
158 int main (int argc
, char *argv
[])
160 int errors
, numsig
, pid
;
162 int do_pid
, do_kill
, check_all
;
166 if ((p
= strrchr(progname
, '/')) != NULL
)
169 setlocale(LC_ALL
, "");
170 bindtextdomain(PACKAGE
, LOCALEDIR
);
172 atexit(close_stdout
);
175 do_pid
= (! strcmp (progname
, "pid")); /* Yecch */
179 /* loop through the arguments.
180 actually, -a is the only option can be used with other options.
181 `kill' is basically a one-option-at-most program. */
182 for (argc
--, argv
++; argc
> 0; argc
--, argv
++) {
187 if (! strcmp (arg
, "--")) {
191 if (! strcmp (arg
, "-v") || ! strcmp (arg
, "-V") ||
192 ! strcmp (arg
, "--version")) {
193 printf(UTIL_LINUX_VERSION
);
196 if (! strcmp (arg
, "-a")) {
200 if (! strcmp (arg
, "-l")) {
202 printsignals (stdout
);
208 /* argc == 2, accept "kill -l $?" */
210 if ((numsig
= arg_to_signum (arg
, 1)) < 0) {
211 fprintf (stderr
, _("%s: unknown signal %s\n"), progname
, arg
);
217 if (! strcmp (arg
, "-p")) {
223 if (! strcmp (arg
, "-s")) {
232 if ((numsig
= arg_to_signum (arg
, 0)) < 0) {
238 if (! strcmp (arg
, "-q")) {
244 sigdata
.sival_int
= strtos32_or_err(arg
, _("invalid sigval argument"));
249 /* `arg' begins with a dash but is not a known option.
250 so it's probably something like -HUP, or -1/-n
252 -n could be signal n, or pid -n (i.e. process group n).
253 In case of doubt POSIX tells us to assume a signal.
254 If a signal has been parsed, assume it's a pid, break */
258 if ((numsig
= arg_to_signum (arg
, 0)) < 0) {
274 /* we're done with the options.
275 the rest of the arguments should be process ids and names.
277 for (errors
= 0; (arg
= *argv
) != NULL
; argv
++) {
278 pid
= strtol (arg
, &ep
, 10);
280 errors
+= kill_verbose (arg
, pid
, numsig
);
282 pids
= get_pids (arg
, check_all
);
285 fprintf (stderr
, _("%s: can't find process \"%s\"\n"),
289 for (ip
= pids
; *ip
>= 0; ip
++)
290 errors
+= kill_verbose (arg
, *ip
, numsig
);
298 static int rtsig_to_signum(char *sig
)
303 if (strncasecmp(sig
, "min+", 4) == 0)
305 else if (strncasecmp(sig
, "max-", 4) == 0) {
314 num
= strtol(sig
, &ep
, 10);
315 if (!ep
|| sig
== ep
|| errno
|| num
< 0)
318 num
= maxi
? SIGRTMAX
- num
: SIGRTMIN
+ num
;
320 if (num
< SIGRTMIN
|| num
> SIGRTMAX
)
327 static int signame_to_signum (char *sig
)
331 if (! strncasecmp (sig
, "sig", 3))
336 if (!strncasecmp(sig
, "rt", 2))
337 return rtsig_to_signum(sig
+ 2);
340 for (n
= 0; n
< ARRAY_SIZE(sys_signame
); n
++) {
341 if (! strcasecmp (sys_signame
[n
].name
, sig
))
342 return sys_signame
[n
].val
;
347 static int arg_to_signum (char *arg
, int maskbit
)
352 if (isdigit (*arg
)) {
353 numsig
= strtol (arg
, &ep
, 10);
354 if (numsig
>= NSIG
&& maskbit
&& (numsig
& 128) != 0)
356 if (*ep
!= 0 || numsig
< 0 || numsig
>= NSIG
)
360 return signame_to_signum (arg
);
363 static void nosig (char *name
)
365 fprintf (stderr
, _("%s: unknown signal %s; valid signals:\n"), progname
, name
);
366 printsignals (stderr
);
369 static void printsig (int sig
)
373 for (n
= 0; n
< ARRAY_SIZE(sys_signame
); n
++) {
374 if (sys_signame
[n
].val
== sig
) {
375 printf ("%s\n", sys_signame
[n
].name
);
380 if (sig
>= SIGRTMIN
&& sig
<= SIGRTMAX
) {
381 printf ("RT%d\n", sig
- SIGRTMIN
);
388 static void printsignals (FILE *fp
)
390 size_t n
, lth
, lpos
= 0;
392 for (n
= 0; n
< ARRAY_SIZE(sys_signame
); n
++) {
393 lth
= 1+strlen(sys_signame
[n
].name
);
400 fputs (sys_signame
[n
].name
, fp
);
403 fputs (" RT<N> RTMIN+<N> RTMAX-<N>", fp
);
408 static int usage (int status
)
412 fp
= (status
== 0 ? stdout
: stderr
);
413 fprintf (fp
, _("usage: %s [ -s signal | -p ] [ -a ] pid ...\n"), progname
);
414 fprintf (fp
, _(" %s -l [ signal ]\n"), progname
);
418 static int kill_verbose (char *procname
, int pid
, int sig
)
423 printf ("%d\n", pid
);
428 rc
= sigqueue(pid
, sig
, sigdata
);
431 rc
= kill (pid
, sig
);
434 fprintf (stderr
, "%s ", progname
);