]> eyrie.org Git - kerberos/kstart.git/commitdiff
Set exit status if child stops via signal
authorAasif Versi <versi786@gmail.com>
Sat, 28 Aug 2021 15:04:43 +0000 (11:04 -0400)
committerAasif Versi <versi786@gmail.com>
Sat, 28 Aug 2021 15:04:43 +0000 (11:04 -0400)
The current implementation of command_finish always calls WEXITSTATUS,
despite the man page for waitpid stating that WEXITSTATUS should only
be used if WIFEXITED returned true.

This change will set the exit status of k5start accordingly by either
using WTERMSIG if WIFSIGNALED returns true, and using WEXITSTATUS if
WIFEXITETED returns true. This means that the user can check the exit
status of the command running under k5start and know if the command
failed. Looking at the following example, in the previous code, the
command would print 0, now it will print 143. This will match the
functionality of bash [0].

$ k5start -f ./user.keytab -- sh -c 'kill $$'; echo $?
143
$ sh -c 'kill $$'; echo $?
143

This also makes a minor change by only setting the status if it is a
non-null pointer.

[0]: https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html

tests/k5start/basic-t
util/command.c

index be2100c519611a5d5873e0f02456c66786104213..3eb608b435c001a800938aa7faec29efdf8494fc 100755 (executable)
@@ -22,7 +22,7 @@ require "$ENV{C_TAP_SOURCE}/libtest.pl";
 
 # Decide whether we have the configuration to run the tests.
 if (-f "$DATA/test.keytab" and -f "$DATA/test.principal") {
-    plan tests => 89;
+    plan tests => 92;
 } else {
     plan skip_all => 'no keytab configuration';
     exit 0;
@@ -289,5 +289,14 @@ is ($status, 3, 'k5start of exit 3 returns correct exit status');
 is ($err, '', ' with no errors');
 ok (!-f 'krb5cc_test', ' and the default cache file was not created');
 
+# Test propagation of exit status from a command which is killed by signal.
+unlink 'krb5cc_test';
+($out, $err, $status)
+    = command ($K5START, '-Uqf', "$DATA/test.keytab", '--', 'sh', '-c',
+               'kill $$');
+is ($status, 143, 'k5start of kill $$ returns correct exit status');
+is ($err, '', ' with no errors');
+ok (!-f 'krb5cc_test', ' and the default cache file was not created');
+
 # Clean up.
 unlink 'krb5cc_test';
index ab2753060483c96cec75ea9ee5eabd21ed36dd60..8fccab7662938cfc035f4585a8caf8cd9dab9b80 100644 (file)
@@ -130,6 +130,14 @@ command_finish(pid_t child, int *status)
         return -1;
     if (result == 0)
         return 0;
-    *status = WEXITSTATUS(*status);
+
+    if (status) {
+        if (WIFEXITED(*status))
+            *status = WEXITSTATUS(*status);
+        else if (WIFSIGNALED(*status))
+            // +128 to match exit status set by bash when process is signaled
+            *status = WTERMSIG(*status) + 128;
+    }
+
     return 1;
 }