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
557fda8f98
commit
cd7ea2abf3
2
kill.1
2
kill.1
@ -5,7 +5,7 @@
|
|||||||
.\" Licensed under version 2 of the GNU General Public License.
|
.\" Licensed under version 2 of the GNU General Public License.
|
||||||
.\" Written by Albert Cahalan; converted to a man page by
|
.\" Written by Albert Cahalan; converted to a man page by
|
||||||
.\" Michael K. Johnson
|
.\" Michael K. Johnson
|
||||||
.TH KILL 1 "October 2011" "procps-ng" "User Commands"
|
.TH KILL 1 "2020-04-24" "procps-ng" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
kill \- send a signal to a process
|
kill \- send a signal to a process
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
27
kill.c
27
kill.c
@ -21,6 +21,7 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ static void __attribute__ ((__noreturn__)) print_usage(FILE * out)
|
|||||||
fputs(_(" <pid> [...] send signal to every <pid> listed\n"), out);
|
fputs(_(" <pid> [...] send signal to every <pid> listed\n"), out);
|
||||||
fputs(_(" -<signal>, -s, --signal <signal>\n"
|
fputs(_(" -<signal>, -s, --signal <signal>\n"
|
||||||
" specify the <signal> to be sent\n"), out);
|
" 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, --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(_(" -L, --table list all signal names in a nice table\n"), out);
|
||||||
fputs(USAGE_SEPARATOR, out);
|
fputs(USAGE_SEPARATOR, out);
|
||||||
@ -48,12 +50,22 @@ static void __attribute__ ((__noreturn__)) print_usage(FILE * out)
|
|||||||
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
|
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static int execute_kill(pid_t pid, int sig_num, const bool use_sigqueue, union sigval sigval)
|
||||||
|
{
|
||||||
|
if (use_sigqueue)
|
||||||
|
return sigqueue(pid, sig_num, sigval);
|
||||||
|
else
|
||||||
|
return kill(pid, sig_num);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int signo, i;
|
int signo, i;
|
||||||
long pid;
|
long pid;
|
||||||
int exitvalue = EXIT_SUCCESS;
|
int exitvalue = EXIT_SUCCESS;
|
||||||
int optindex;
|
int optindex;
|
||||||
|
union sigval sigval;
|
||||||
|
bool use_sigqueue = false;
|
||||||
char *sig_option;
|
char *sig_option;
|
||||||
|
|
||||||
static const struct option longopts[] = {
|
static const struct option longopts[] = {
|
||||||
@ -62,6 +74,7 @@ int main(int argc, char **argv)
|
|||||||
{"signal", required_argument, NULL, 's'},
|
{"signal", required_argument, NULL, 's'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"version", no_argument, NULL, 'V'},
|
{"version", no_argument, NULL, 'V'},
|
||||||
|
{"queue", required_argument, NULL, 'q'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -79,7 +92,7 @@ int main(int argc, char **argv)
|
|||||||
signo = SIGTERM;
|
signo = SIGTERM;
|
||||||
|
|
||||||
opterr=0; /* suppress errors on -123 */
|
opterr=0; /* suppress errors on -123 */
|
||||||
while ((i = getopt_long(argc, argv, "l::Ls:hV", longopts, &optindex)) != -1)
|
while ((i = getopt_long(argc, argv, "l::Ls:hVq:", longopts, &optindex)) != -1)
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 'l':
|
case 'l':
|
||||||
sig_option = NULL;
|
sig_option = NULL;
|
||||||
@ -112,6 +125,10 @@ int main(int argc, char **argv)
|
|||||||
case 'V':
|
case 'V':
|
||||||
fprintf(stdout, PROCPS_NG_VERSION);
|
fprintf(stdout, PROCPS_NG_VERSION);
|
||||||
exit(EXIT_SUCCESS);
|
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 '?':
|
case '?':
|
||||||
if (!isdigit(optopt)) {
|
if (!isdigit(optopt)) {
|
||||||
xwarnx(_("invalid argument %c"), optopt);
|
xwarnx(_("invalid argument %c"), optopt);
|
||||||
@ -119,9 +136,9 @@ int main(int argc, char **argv)
|
|||||||
} else {
|
} else {
|
||||||
/* Special case for signal digit negative
|
/* Special case for signal digit negative
|
||||||
* PIDs */
|
* PIDs */
|
||||||
pid = (long)('0' - optopt);
|
pid = (long)('0' - optopt);
|
||||||
if (kill((pid_t)pid, signo) != 0)
|
if (!execute_kill((pid_t) pid, signo, use_sigqueue, sigval))
|
||||||
exitvalue = EXIT_FAILURE;
|
exitvalue = EXIT_FAILURE;
|
||||||
exit(exitvalue);
|
exit(exitvalue);
|
||||||
}
|
}
|
||||||
xerrx(EXIT_FAILURE, _("internal error"));
|
xerrx(EXIT_FAILURE, _("internal error"));
|
||||||
@ -137,7 +154,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
pid = strtol_or_err(argv[i], _("failed to parse argument"));
|
pid = strtol_or_err(argv[i], _("failed to parse argument"));
|
||||||
if (!kill((pid_t) pid, signo))
|
if (!execute_kill((pid_t) pid, signo, use_sigqueue, sigval))
|
||||||
continue;
|
continue;
|
||||||
error(0, errno, "(%ld)", pid);
|
error(0, errno, "(%ld)", pid);
|
||||||
exitvalue = EXIT_FAILURE;
|
exitvalue = EXIT_FAILURE;
|
||||||
|
@ -10,7 +10,7 @@ if { ![ file exists $kill ] } {
|
|||||||
|
|
||||||
set test "kill with no arguments"
|
set test "kill with no arguments"
|
||||||
spawn $kill
|
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"
|
set test "kill list signal names"
|
||||||
spawn $kill -l
|
spawn $kill -l
|
||||||
|
Loading…
Reference in New Issue
Block a user