From aa41c309dd393933671e0cedaf8ebe0432ab24c4 Mon Sep 17 00:00:00 2001 From: Craig Small Date: Mon, 22 May 2017 22:15:59 +1000 Subject: [PATCH] kill: -l space between name parses correctly This was supposed to be just a cherry-pick of the referenced commit. However there were two problems: 1. kill code was moved out to its own file 2. strtosig() had a latent bug where signal numbers were not converted to names. Original note: kill -lHUP would work correctly, but kill -l HUP would not. The list option in kill was hit by a quirk of getopt_long where an option with an optional argument would not attempt to get the argument beyond the space, even though a mandatory argument would do that. The fix is a kludge to scan to the next argument and if it looks like something we can use, use it. Lucky for us, the list option is one where parsing can stop immediately. Thanks to Brian Vandenberg for the way forward. References: http://stackoverflow.com/questions/1052746/getopt-does-not-parse-optional-arguments-to-parameters https://bugs.debian.org/854407 commit 537cea324b121f54744369425332c256aa84a181 --- NEWS | 1 + kill.c | 14 +++++++++++--- lib/signals.c | 5 +++-- testsuite/kill.test/kill.exp | 19 ++++++++++++++++--- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 81616a19..3b621d19 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ procps-ng-NEXT ---------------- + * kill: -l space between name parses correctly Debian #854407 * library: dont use vm_min_free on non Linux Debian #831396 * library: dont use SIGPWR on FreeBSD Debian #832148 * library: don't strip off wchan prefixes (ps & top) Redhat #1322111 diff --git a/kill.c b/kill.c index b3c9a5fe..ecace65b 100644 --- a/kill.c +++ b/kill.c @@ -53,6 +53,8 @@ int main(int argc, char **argv) int signo, i, loop=1; long pid; int exitvalue = EXIT_SUCCESS; + int optindex; + char *sig_option; static const struct option longopts[] = { {"list", optional_argument, NULL, 'l'}, @@ -77,17 +79,23 @@ int main(int argc, char **argv) signo = SIGTERM; opterr=0; /* suppress errors on -123 */ - while (loop == 1 && (i = getopt_long(argc, argv, "l::Ls:hV", longopts, NULL)) != -1) + while (loop == 1 && (i = getopt_long(argc, argv, "l::Ls:hV", longopts, &optindex)) != -1) switch (i) { case 'l': + sig_option = NULL; if (optarg) { + sig_option = optarg; + } else if (argv[optind] != NULL && argv[optind][0] != '-') { + sig_option = argv[optind]; + } + if (sig_option) { char *s; - s = strtosig(optarg); + s = strtosig(sig_option); if (s) printf("%s\n", s); else xwarnx(_("unknown signal name %s"), - optarg); + sig_option); free(s); } else { unix_print_signals(); diff --git a/lib/signals.c b/lib/signals.c index d85c1fd9..fbf3dc73 100644 --- a/lib/signals.c +++ b/lib/signals.c @@ -240,9 +240,10 @@ char *strtosig(const char *restrict s) p += 3; if (isdigit(*p)){ numsignal = strtol(s,&endp,10); - if(*endp || endp==s) + if(*endp || endp==s){ free(p); - return NULL; /* not valid */ + return NULL; /* not valid */ + } } if (numsignal){ for (i = 0; i < number_of_signals; i++){ diff --git a/testsuite/kill.test/kill.exp b/testsuite/kill.test/kill.exp index 211395c9..1948517f 100644 --- a/testsuite/kill.test/kill.exp +++ b/testsuite/kill.test/kill.exp @@ -20,15 +20,28 @@ set test "kill list signal names in table" spawn $kill -L expect_pass "$test" "^\(\\s+\\d+ \[A-Z12+-\]+\)+\\s*$" -set test "kill convert signal name to number" +set test "kill convert signal name to number no space" spawn $kill -lHUP expect_pass "$test" "^1\\s*" -set test "kill convert SIG-prefixed signal name to number" +set test "kill convert signal name to number with space" +spawn $kill -l HUP +expect_pass "$test" "^1\\s*" + +set test "kill convert SIG-prefixed signal name to number no space" spawn $kill -lSIGHUP expect_pass "$test" "^1\\s*$" -set test "kill convert signal number to name" +set test "kill convert SIG-prefixed signal name to number with space" +spawn $kill -l SIGHUP + +expect_pass "$test" "^1\\s*$" + +set test "kill convert signal number to name no space" +spawn $kill -l1 +expect_pass "$test" "^HUP\\s*" + +set test "kill convert signal number to name with space" spawn $kill -l 1 expect_pass "$test" "^HUP\\s*"