From 536cea324b121f54744369425332c256aa84a181 Mon Sep 17 00:00:00 2001 From: Craig Small Date: Tue, 7 Feb 2017 22:05:18 +1100 Subject: [PATCH] kill: -l space between name parses correctly 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 --- NEWS | 1 + skill.c | 16 ++++++++++++---- testsuite/kill.test/kill.exp | 19 ++++++++++++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index e7597d2e..99d7d84a 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ procps-ng-NEXT * top: add config file support for XDG specification * pgrep: warn about 15+ char name only if -f not used * pkill: Return 0 only if we can kill process Debian #852758 + * kill: -l space between name parses correctly Debian #854407 procps-ng-3.3.12 ---------------- diff --git a/skill.c b/skill.c index 36210409..5d233c25 100644 --- a/skill.c +++ b/skill.c @@ -422,6 +422,8 @@ static void __attribute__ ((__noreturn__)) int loop = 1; long pid; int exitvalue = EXIT_SUCCESS; + int optindex; + char *sig_option; static const struct option longopts[] = { {"list", optional_argument, NULL, 'l'}, @@ -445,17 +447,23 @@ static void __attribute__ ((__noreturn__)) 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': - if (optarg) { + sig_option = NULL; + if (optarg) { + sig_option = optarg; + } else if (argv[optindex+1] != NULL && argv[optindex+1][0] != '-') { + sig_option = argv[optindex+1]; + } + 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/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*"