When a child process terminates through a signal, the convention in posix_spawn is that the parent process sees an exit code of 127. This convention should also hold for the 'execute' module. On native Windows, this requires mapping the exit code 3 (from Microsoft) to exit code 127 (per POSIX).
2020-12-24 Bruno Haible <br...@clisp.org> execute: Treat signalled processes like wait-process does. * lib/execute.c: Include <sys/types.h>, <sys/wait.h>. (execute): Recognize the case where the exit code indicates a signalled child process. * tests/test-execute-main.c (main): Update expected test result. * modules/execute (Depends-on): Add sys_wait. diff --git a/lib/execute.c b/lib/execute.c index 38dd07b..4cc779e 100644 --- a/lib/execute.c +++ b/lib/execute.c @@ -28,6 +28,9 @@ #include <signal.h> #include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> + #include "canonicalize.h" #include "error.h" #include "fatal-signal.h" @@ -214,12 +217,22 @@ execute (const char *progname, free (argv_mem_to_free); free (prog_path_to_free); + /* Treat failure and signalled child processes like wait_subprocess() + does. */ if (termsigp != NULL) *termsigp = 0; if (exitcode == -1) goto fail_with_saved_errno; + if (WIFSIGNALED (exitcode)) + { + if (termsigp != NULL) + *termsigp = WTERMSIG (exitcode); + saved_errno = 0; + goto fail_with_saved_errno; + } + return exitcode; #else diff --git a/modules/execute b/modules/execute index 90a7b89..4345580 100644 --- a/modules/execute +++ b/modules/execute @@ -29,6 +29,7 @@ posix_spawnattr_setflags posix_spawnattr_destroy stdbool stdlib +sys_wait unistd wait-process windows-spawn diff --git a/tests/test-execute-main.c b/tests/test-execute-main.c index c58a62d..29a4c30 100644 --- a/tests/test-execute-main.c +++ b/tests/test-execute-main.c @@ -135,11 +135,10 @@ main (int argc, char *argv[]) int termsig = 0xDEADBEEF; int ret = execute (progname, prog_argv[0], prog_argv, NULL, false, false, false, false, true, false, &termsig); + ASSERT (ret == 127); #if defined _WIN32 && !defined __CYGWIN__ - ASSERT (ret == 3); - ASSERT (termsig == 0); + ASSERT (termsig == SIGTERM); /* dummy, from WTERMSIG in <sys/wait.h> */ #else - ASSERT (ret == 127); ASSERT (termsig == SIGINT); #endif }