From 9db9b34adaad1a9ebe892eaea486cfe0610bad8d Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Wed, 5 Apr 2023 09:32:42 +0100 Subject: win32: ignore ctrl-c in parent of execve(2) The execve(2) system call is emulated for Microsoft Windows. This requires the creation of a new process. The old process remains active, waiting for the "execed" child to exit so it can pass on its exit status. Previously this was achieved using P_WAIT mode in the call to spawnve(). However the parent of the execve(2) process may still be able to catch Ctrl-C interrupts. This can lead to unwanted behaviour, such as a shell and its children competing for input. Force the waiting process to ignore Ctrl-C interrupts. Costs 64-80 bytes. (GitHub issue #303) --- win32/process.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/win32/process.c b/win32/process.c index 428d6c703..1ee576055 100644 --- a/win32/process.c +++ b/win32/process.c @@ -408,21 +408,31 @@ mingw_spawn_proc(const char **argv) return mingw_spawnvp(P_NOWAIT, argv[0], (char *const *)argv); } +static NORETURN void wait_for_child(HANDLE child) +{ + DWORD code; + + SetConsoleCtrlHandler(NULL, TRUE); + WaitForSingleObject(child, INFINITE); + GetExitCodeProcess(child, &code); + exit((int)code); +} + int mingw_execvp(const char *cmd, char *const *argv) { - int ret = (int)mingw_spawnvp(P_WAIT, cmd, argv); + intptr_t ret = mingw_spawnvp(P_NOWAIT, cmd, argv); if (ret != -1 || errno == 0) - exit(ret); + wait_for_child((HANDLE)ret); return ret; } int mingw_execve(const char *cmd, char *const *argv, char *const *envp) { - int ret = (int)mingw_spawn_interpreter(P_WAIT, cmd, argv, envp, 0); + intptr_t ret = mingw_spawn_interpreter(P_NOWAIT, cmd, argv, envp, 0); if (ret != -1 || errno == 0) - exit(ret); + wait_for_child((HANDLE)ret); return ret; } -- cgit v1.2.3-55-g6feb