]> granicus.if.org Git - procps-ng/commitdiff
kill: use sigqueue to pass value with the signal.
authorArun Chandrasekaran <aruncxy@gmail.com>
Fri, 24 Apr 2020 09:22:47 +0000 (19:22 +1000)
committerCraig Small <csmall@dropbear.xyz>
Fri, 24 Apr 2020 09:22:47 +0000 (19:22 +1000)
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>
kill.1
skill.c
testsuite/kill.test/kill.exp

diff --git a/kill.1 b/kill.1
index dd53040c5d4902ba4fc0e4dfa2136098c9849f1c..a15f0ba56a950ad39508afd430623cc4293b18e5 100644 (file)
--- a/kill.1
+++ b/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.
diff --git a/skill.c b/skill.c
index c91aa7b79353bdee330b4075d298d896826f1bf5..5a79a41cab08ff2019b87687ba14f4a2360c38c9 100644 (file)
--- a/skill.c
+++ b/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;
index 1948517f2c7896665b44c1705ef0c08770dbba1b..fb5fda73aeff9d82d1cd67ea6ac4ae39f986ace4 100644 (file)
@@ -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