]> 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>
Mon, 11 May 2020 07:36:12 +0000 (17:36 +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
kill.c
testsuite/kill.test/kill.exp

diff --git a/kill.1 b/kill.1
index 62be918d685dcb6b1f4cc517049efb5f3bf91cd8..fef1adc1966060774108ab62dd738b4b47def808 100644 (file)
--- a/kill.1
+++ b/kill.1
@@ -5,7 +5,7 @@
 .\" Licensed under version 2 of the GNU General Public License.
 .\" Written by Albert Cahalan; converted to a man page by
 .\" Michael K. Johnson
-.TH KILL 1 "October 2011" "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
diff --git a/kill.c b/kill.c
index 6fa3a4cbcb0fae46f1ec58ca4da50cd1d27cfb39..8c85970c94320b7fd10dfb6395eb98154635254b 100644 (file)
--- a/kill.c
+++ b/kill.c
@@ -21,6 +21,7 @@
 #include <getopt.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <signal.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(_(" -<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);
@@ -48,12 +50,22 @@ static void __attribute__ ((__noreturn__)) print_usage(FILE * out)
     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 signo, i;
     long pid;
     int exitvalue = EXIT_SUCCESS;
     int optindex;
+    union sigval sigval;
+    bool use_sigqueue = false;
     char *sig_option;
 
     static const struct option longopts[] = {
@@ -62,6 +74,7 @@ int main(int argc, char **argv)
         {"signal", required_argument, NULL, 's'},
         {"help", no_argument, NULL, 'h'},
         {"version", no_argument, NULL, 'V'},
+        {"queue", required_argument, NULL, 'q'},
         {NULL, 0, NULL, 0}
     };
 
@@ -79,7 +92,7 @@ int main(int argc, char **argv)
         signo = SIGTERM;
 
     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) {
         case 'l':
             sig_option = NULL;
@@ -112,6 +125,10 @@ int main(int argc, char **argv)
         case 'V':
             fprintf(stdout, PROCPS_NG_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);
@@ -119,9 +136,9 @@ int main(int argc, char **argv)
             } else {
                 /* Special case for signal digit negative
                  * PIDs */
-                pid = (long)('0' - optopt);
-                if (kill((pid_t)pid, signo) != 0)
-                exitvalue = EXIT_FAILURE;
+               pid = (long)('0' - optopt);
+               if (!execute_kill((pid_t) pid, signo, use_sigqueue, sigval))
+                   exitvalue = EXIT_FAILURE;
                 exit(exitvalue);
             }
             xerrx(EXIT_FAILURE, _("internal error"));
@@ -137,7 +154,7 @@ int main(int argc, char **argv)
 
     for (i = 0; i < argc; i++) {
         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;
         error(0, errno, "(%ld)", pid);
         exitvalue = EXIT_FAILURE;
index 2032e0e5de94c074ca95733288084f23ed9e143c..5aa7b2c98609f448875866e5bccd359d7773eaa6 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