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 numbers 128+s.
43 * Copyright (C) 2014 Sami Kerola <kerolasa@iki.fi>
44 * Copyright (C) 2014 Karel Zak <kzak@redhat.com>
47 #include <ctype.h> /* for isdigit() */
55 #include "closestream.h"
57 #include "pidfd-utils.h"
59 #include "pathnames.h"
64 #include "fileutils.h"
66 /* partial success, otherwise we return regular EXIT_{SUCCESS,FAILURE} */
67 #define KILL_EXIT_SOMEOK 64
70 KILL_FIELD_WIDTH
= 11,
71 KILL_OUTPUT_WIDTH
= 72
80 struct list_head follow_ups
;
92 struct list_head follow_ups
;
106 static void print_signal_name(int signum
)
108 const char *name
= signum_to_signame(signum
);
111 printf("%s\n", name
);
115 if (SIGRTMIN
<= signum
&& signum
<= SIGRTMAX
) {
116 printf("RT%d\n", signum
- SIGRTMIN
);
120 printf("%d\n", signum
);
123 static void pretty_print_signal(FILE *fp
, size_t term_width
, size_t *lpos
,
124 int signum
, const char *name
)
126 if (term_width
< (*lpos
+ KILL_FIELD_WIDTH
)) {
130 *lpos
+= KILL_FIELD_WIDTH
;
131 fprintf(fp
, "%2d %-8s", signum
, name
);
134 static void print_all_signals(FILE *fp
, int pretty
)
136 size_t n
, lth
, lpos
= 0, width
;
137 const char *signame
= NULL
;
141 for (n
= 0; get_signame_by_idx(n
, &signame
, NULL
) == 0; n
++) {
142 lth
= 1 + strlen(signame
);
143 if (KILL_OUTPUT_WIDTH
< lpos
+ lth
) {
152 fputs(" RT<N> RTMIN+<N> RTMAX-<N>", fp
);
159 width
= get_terminal_width(KILL_OUTPUT_WIDTH
+ 1) - 1;
160 for (n
= 0; get_signame_by_idx(n
, &signame
, &signum
) == 0; n
++)
161 pretty_print_signal(fp
, width
, &lpos
, signum
, signame
);
163 pretty_print_signal(fp
, width
, &lpos
, SIGRTMIN
, "RTMIN");
164 pretty_print_signal(fp
, width
, &lpos
, SIGRTMAX
, "RTMAX");
169 static void err_nosig(char *name
)
171 warnx(_("unknown signal %s; valid signals:"), name
);
172 print_all_signals(stderr
, 1);
176 static int arg_to_signum(char *arg
, int maskbit
)
183 numsig
= strtol(arg
, &ep
, 10);
184 if (NSIG
<= numsig
&& maskbit
&& (numsig
& 128) != 0)
186 if (errno
|| *ep
!= 0 || numsig
< 0 || NSIG
<= numsig
)
190 return signame_to_signum(arg
);
193 static void __attribute__((__noreturn__
)) usage(void)
196 fputs(USAGE_HEADER
, out
);
197 fprintf(out
, _(" %s [options] <pid>|<name>...\n"), program_invocation_short_name
);
199 fputs(USAGE_SEPARATOR
, out
);
200 fputs(_("Forcibly terminate a process.\n"), out
);
202 fputs(USAGE_OPTIONS
, out
);
203 fputs(_(" -a, --all do not restrict the name-to-pid conversion to processes\n"
204 " with the same uid as the present process\n"), out
);
205 fputs(_(" -s, --signal <signal> send this <signal> instead of SIGTERM\n"), out
);
207 fputs(_(" -q, --queue <value> use sigqueue(2), not kill(2), and pass <value> as data\n"), out
);
210 fputs(_(" --timeout <milliseconds> <follow-up signal>\n"
211 " wait up to timeout and send follow-up signal\n"), out
);
213 fputs(_(" -p, --pid print pids without signaling them\n"), out
);
214 fputs(_(" -l, --list[=<signal>] list signal names, or convert a signal number to a name\n"), out
);
215 fputs(_(" -L, --table list signal names and numbers\n"), out
);
216 fputs(_(" -r, --require-handler do not send signal if signal handler is not present\n"), out
);
217 fputs(_(" --verbose print pids that will be signaled\n"), out
);
219 fputs(USAGE_SEPARATOR
, out
);
220 fprintf(out
, USAGE_HELP_OPTIONS(24));
221 fprintf(out
, USAGE_MAN_TAIL("kill(1)"));
226 static void __attribute__((__noreturn__
)) print_kill_version(void)
228 static const char *features
[] = {
237 printf(_("%s from %s"), program_invocation_short_name
, PACKAGE_STRING
);
239 if (ARRAY_SIZE(features
)) {
241 fputs(_(" (with: "), stdout
);
242 for (i
= 0; i
< ARRAY_SIZE(features
); i
++) {
243 fputs(features
[i
], stdout
);
244 if (i
+ 1 < ARRAY_SIZE(features
))
247 fputs(")\n", stdout
);
252 static char **parse_arguments(int argc
, char **argv
, struct kill_control
*ctl
)
256 /* Loop through the arguments. Actually, -a is the only option
257 * can be used with other options. The 'kill' is basically a
258 * one-option-at-most program. */
259 for (argc
--, argv
++; 0 < argc
; argc
--, argv
++) {
263 if (!strcmp(arg
, "--")) {
267 if (!strcmp(arg
, "-v") || !strcmp(arg
, "-V") ||
268 !strcmp(arg
, "--version"))
269 print_kill_version();
270 if (!strcmp(arg
, "-h") || !strcmp(arg
, "--help"))
272 if (!strcmp(arg
, "--verbose")) {
276 if (!strcmp(arg
, "-a") || !strcmp(arg
, "--all")) {
280 if (!strcmp(arg
, "-l") || !strcmp(arg
, "--list")) {
282 print_all_signals(stdout
, 0);
286 errx(EXIT_FAILURE
, _("too many arguments"));
287 /* argc == 2, accept "kill -l $?" */
289 if ((ctl
->numsig
= arg_to_signum(arg
, 1)) < 0)
290 errx(EXIT_FAILURE
, _("unknown signal: %s"),
292 print_signal_name(ctl
->numsig
);
295 /* for compatibility with procps kill(1) */
296 if (!strncmp(arg
, "--list=", 7) || !strncmp(arg
, "-l=", 3)) {
297 char *p
= strchr(arg
, '=') + 1;
298 if ((ctl
->numsig
= arg_to_signum(p
, 1)) < 0)
299 errx(EXIT_FAILURE
, _("unknown signal: %s"), p
);
300 print_signal_name(ctl
->numsig
);
303 if (!strcmp(arg
, "-L") || !strcmp(arg
, "--table")) {
304 print_all_signals(stdout
, 1);
307 if (!strcmp(arg
, "-r") || !strcmp(arg
, "--require-handler")) {
308 ctl
->require_handler
= 1;
311 if (!strcmp(arg
, "-p") || !strcmp(arg
, "--pid")) {
314 errx(EXIT_FAILURE
, _("%s and %s are mutually exclusive"), "--pid", "--signal");
317 errx(EXIT_FAILURE
, _("%s and %s are mutually exclusive"), "--pid", "--queue");
321 if (!strcmp(arg
, "-s") || !strcmp(arg
, "--signal")) {
323 errx(EXIT_FAILURE
, _("not enough arguments"));
326 errx(EXIT_FAILURE
, _("%s and %s are mutually exclusive"), "--pid", "--signal");
329 if ((ctl
->numsig
= arg_to_signum(arg
, 0)) < 0)
334 if (!strcmp(arg
, "-q") || !strcmp(arg
, "--queue")) {
336 errx(EXIT_FAILURE
, _("option '%s' requires an argument"), arg
);
338 errx(EXIT_FAILURE
, _("%s and %s are mutually exclusive"), "--pid", "--queue");
341 ctl
->sigdata
.sival_int
= strtos32_or_err(arg
, _("argument error"));
347 if (!strcmp(arg
, "--timeout")) {
348 struct timeouts
*next
;
352 errx(EXIT_FAILURE
, _("option '%s' requires an argument"), arg
);
355 next
= xcalloc(1, sizeof(*next
));
356 next
->period
= strtos32_or_err(arg
, _("argument error"));
357 INIT_LIST_HEAD(&next
->follow_ups
);
360 if ((next
->sig
= arg_to_signum(arg
, 0)) < 0)
362 list_add_tail(&next
->follow_ups
, &ctl
->follow_ups
);
366 /* 'arg' begins with a dash but is not a known option.
367 * So it's probably something like -HUP, or -1/-n try to
370 * -n could be either signal n or pid -n (a process group
371 * number). In case of doubt, POSIX tells us to assume a
372 * signal. But if a signal has already been parsed, then
373 * assume it is a process group, so stop parsing options. */
377 if ((ctl
->numsig
= arg_to_signum(arg
, 0)) < 0)
378 errx(EXIT_FAILURE
, _("invalid signal name or number: %s"), arg
);
381 errx(EXIT_FAILURE
, _("%s and %s are mutually exclusive"), "--pid", "--signal");
384 errx(EXIT_FAILURE
, _("not enough arguments"));
389 static int kill_with_timeout(const struct kill_control
*ctl
)
392 struct pollfd p
= { 0 };
393 siginfo_t info
= { 0 };
394 struct list_head
*entry
;
396 info
.si_code
= SI_QUEUE
;
397 info
.si_signo
= ctl
->numsig
;
398 info
.si_uid
= getuid();
399 info
.si_pid
= getpid();
400 info
.si_value
.sival_int
=
401 ctl
->use_sigval
!= 0 ? ctl
->use_sigval
: ctl
->numsig
;
403 if ((pfd
= pidfd_open(ctl
->pid
, 0)) < 0)
404 err(EXIT_FAILURE
, _("pidfd_open() failed: %d"), ctl
->pid
);
408 if (pidfd_send_signal(pfd
, ctl
->numsig
, &info
, 0) < 0)
409 err(EXIT_FAILURE
, _("pidfd_send_signal() failed"));
410 list_for_each(entry
, &ctl
->follow_ups
) {
411 struct timeouts
*timeout
;
413 timeout
= list_entry(entry
, struct timeouts
, follow_ups
);
414 n
= poll(&p
, 1, timeout
->period
);
416 err(EXIT_FAILURE
, _("poll() failed"));
418 info
.si_signo
= timeout
->sig
;
420 printf(_("timeout, sending signal %d to pid %d\n"),
421 timeout
->sig
, ctl
->pid
);
422 if (pidfd_send_signal(pfd
, timeout
->sig
, &info
, 0) < 0)
423 err(EXIT_FAILURE
, _("pidfd_send_signal() failed"));
430 static int kill_verbose(const struct kill_control
*ctl
)
435 printf(_("sending signal %d to pid %d\n"), ctl
->numsig
, ctl
->pid
);
437 printf("%ld\n", (long) ctl
->pid
);
442 rc
= kill_with_timeout(ctl
);
447 rc
= sigqueue(ctl
->pid
, ctl
->numsig
, ctl
->sigdata
);
450 rc
= kill(ctl
->pid
, ctl
->numsig
);
453 warn(_("sending signal to %s failed"), ctl
->arg
);
457 static int check_signal_handler(const struct kill_control
*ctl
)
459 uintmax_t sigcgt
= 0;
460 int rc
= 0, has_hnd
= 0;
463 if (!ctl
->require_handler
)
466 pc
= ul_new_procfs_path(ctl
->pid
, NULL
);
470 rc
= procfs_process_get_stat_nth(pc
, 34, &sigcgt
);
476 has_hnd
= ((1UL << (ctl
->numsig
- 1)) & sigcgt
) != 0;
477 if (ctl
->verbose
&& !has_hnd
)
478 printf(_("not signalling pid %d, it has no userspace handler for signal %d\n"), ctl
->pid
, ctl
->numsig
);
483 int main(int argc
, char **argv
)
485 struct kill_control ctl
= { .numsig
= SIGTERM
};
486 int nerrs
= 0, ct
= 0;
488 setlocale(LC_ALL
, "");
489 bindtextdomain(PACKAGE
, LOCALEDIR
);
491 close_stdout_atexit();
494 INIT_LIST_HEAD(&ctl
.follow_ups
);
496 argv
= parse_arguments(argc
, argv
, &ctl
);
498 /* The rest of the arguments should be process ids and names. */
499 for ( ; (ctl
.arg
= *argv
) != NULL
; argv
++) {
503 ctl
.pid
= strtol(ctl
.arg
, &ep
, 10);
504 if (errno
== 0 && ep
&& *ep
== '\0' && ctl
.arg
< ep
) {
505 if (check_signal_handler(&ctl
) <= 0)
507 if (kill_verbose(&ctl
) != 0)
513 DIR *dir
= opendir(_PATH_PROC
);
514 uid_t uid
= !ctl
.check_all
? getuid() : 0;
519 while ((d
= xreaddir(dir
))) {
520 if (!ctl
.check_all
&&
521 !procfs_dirent_match_uid(dir
, d
, uid
))
524 !procfs_dirent_match_name(dir
, d
, ctl
.arg
))
526 if (procfs_dirent_get_pid(d
, &ctl
.pid
) != 0)
528 if (check_signal_handler(&ctl
) <= 0)
531 if (kill_verbose(&ctl
) != 0)
540 warnx(_("cannot find process \"%s\""), ctl
.arg
);
546 while (!list_empty(&ctl
.follow_ups
)) {
547 struct timeouts
*x
= list_entry(ctl
.follow_ups
.next
,
548 struct timeouts
, follow_ups
);
549 list_del(&x
->follow_ups
);
553 if (ct
&& nerrs
== 0)
554 return EXIT_SUCCESS
; /* full success */
556 return EXIT_FAILURE
; /* all failed */
558 return KILL_EXIT_SOMEOK
; /* partial success */