kill: use sigqueue to pass value with the signal.
New -q/--queue option for kill so it will send an integer to the signalled process. See sigqueue(3) for details. References: https://pubs.opengroup.org/onlinepubs/009695399/functions/sigqueue.html procps-ng/procps!32 Signed-off-by: Craig Small <csmall@dropbear.xyz>
This commit is contained in:
parent
1f5e037d4f
commit
2b804a532a
14
kill.1
14
kill.1
@ -6,7 +6,7 @@ it under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
..
|
||||
.TH KILL 1 "2018-05-31" "procps-ng" "User Commands"
|
||||
.TH KILL 1 "2020-04-24" "procps-ng" "User Commands"
|
||||
.SH NAME
|
||||
kill \- send a signal to a process
|
||||
.SH SYNOPSIS
|
||||
@ -45,6 +45,18 @@ The behavior of signals is explained in
|
||||
.BR signal (7)
|
||||
manual page.
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-queue \fIvalue\fP
|
||||
Use
|
||||
.BR sigqueue(2)
|
||||
rather than
|
||||
.BR kill(2)
|
||||
and the value argument is used to specify
|
||||
an integer to be sent with the signal. If the receiving process has
|
||||
installed a handler for this signal using the SA_SIGINFO flag to
|
||||
.BR sigaction(2)
|
||||
, then it can obtain this data via the si_value field of the
|
||||
siginfo_t structure.
|
||||
.TP
|
||||
\fB\-l\fR, \fB\-\-list\fR [\fIsignal\fR]
|
||||
List signal names. This option has optional argument, which
|
||||
will convert signal number to signal name, or other way round.
|
||||
|
19
skill.c
19
skill.c
@ -26,6 +26,7 @@
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/resource.h>
|
||||
@ -341,6 +342,7 @@ static void __attribute__ ((__noreturn__)) kill_usage(FILE * out)
|
||||
fputs(_(" <pid> [...] send signal to every <pid> listed\n"), out);
|
||||
fputs(_(" -<signal>, -s, --signal <signal>\n"
|
||||
" specify the <signal> to be sent\n"), out);
|
||||
fputs(_(" -q, --queue <value> integer value to be sent with the signal\n"), out);
|
||||
fputs(_(" -l, --list=[<signal>] list all signal names, or convert one to a name\n"), out);
|
||||
fputs(_(" -L, --table list all signal names in a nice table\n"), out);
|
||||
fputs(USAGE_SEPARATOR, out);
|
||||
@ -434,7 +436,9 @@ static void __attribute__ ((__noreturn__))
|
||||
int signo, i;
|
||||
long pid;
|
||||
int exitvalue = EXIT_SUCCESS;
|
||||
char *sig_option;
|
||||
union sigval sigval;
|
||||
bool use_sigqueue = false;
|
||||
char *sig_option;
|
||||
|
||||
static const struct option longopts[] = {
|
||||
{"list", optional_argument, NULL, 'l'},
|
||||
@ -442,6 +446,7 @@ static void __attribute__ ((__noreturn__))
|
||||
{"signal", required_argument, NULL, 's'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"version", no_argument, NULL, 'V'},
|
||||
{"queue", required_argument, NULL, 'q'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
@ -458,7 +463,7 @@ static void __attribute__ ((__noreturn__))
|
||||
signo = SIGTERM;
|
||||
|
||||
opterr=0; /* suppress errors on -123 */
|
||||
while ((i = getopt_long(argc, argv, "l::Ls:hV", longopts, NULL)) != -1)
|
||||
while ((i = getopt_long(argc, argv, "l::Ls:hVq:", longopts, NULL)) != -1)
|
||||
switch (i) {
|
||||
case 'l':
|
||||
sig_option = NULL;
|
||||
@ -491,6 +496,10 @@ static void __attribute__ ((__noreturn__))
|
||||
case 'V':
|
||||
display_kill_version();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'q':
|
||||
sigval.sival_int = strtol_or_err(optarg, _("must be an integer value to be passed with the signal."));
|
||||
use_sigqueue = true;
|
||||
break;
|
||||
case '?':
|
||||
if (!isdigit(optopt)) {
|
||||
xwarnx(_("invalid argument %c"), optopt);
|
||||
@ -516,7 +525,11 @@ static void __attribute__ ((__noreturn__))
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
pid = strtol_or_err(argv[i], _("failed to parse argument"));
|
||||
if (!kill((pid_t) pid, signo))
|
||||
if (use_sigqueue) {
|
||||
if (!sigqueue((pid_t) pid, signo, sigval))
|
||||
continue;
|
||||
}
|
||||
else if (!kill((pid_t) pid, signo))
|
||||
continue;
|
||||
error(0, errno, "(%ld)", pid);
|
||||
exitvalue = EXIT_FAILURE;
|
||||
|
@ -10,7 +10,7 @@ if { ![ file exists $kill ] } {
|
||||
|
||||
set test "kill with no arguments"
|
||||
spawn $kill
|
||||
expect_pass "$test" "Usage:\\s+\(lt-\)?kill \\\[options\\\] <pid> \\\[...\\\]\\s+Options:\\s+<pid> \\\[...\\\]\\s+send signal to every <pid> listed\\s+-<signal>, -s, --signal <signal>\\s+specify the <signal> to be sent\\s+-l, --list=\\\[<signal>\\\]\\s+list all signal names, or convert one to a name\\\s+-L, --table\\s+list all signal names in a nice table$usage_help$usage_version$usage_man"
|
||||
expect_pass "$test" "Usage:\\s+\(lt-\)?kill \\\[options\\\] <pid>"
|
||||
|
||||
set test "kill list signal names"
|
||||
spawn $kill -l
|
||||
|
Loading…
Reference in New Issue
Block a user