aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-04-05 09:32:42 +0100
committerRon Yorston <rmy@pobox.com>2023-04-05 09:32:42 +0100
commit9db9b34adaad1a9ebe892eaea486cfe0610bad8d (patch)
treeae7b191ef7421c861ce1ee96e2564f6ba3283c8b
parentd4494ebdeb3340f98a7a79244601b5d574ae36d1 (diff)
downloadbusybox-w32-9db9b34adaad1a9ebe892eaea486cfe0610bad8d.tar.gz
busybox-w32-9db9b34adaad1a9ebe892eaea486cfe0610bad8d.tar.bz2
busybox-w32-9db9b34adaad1a9ebe892eaea486cfe0610bad8d.zip
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)
-rw-r--r--win32/process.c18
1 files 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)
408 return mingw_spawnvp(P_NOWAIT, argv[0], (char *const *)argv); 408 return mingw_spawnvp(P_NOWAIT, argv[0], (char *const *)argv);
409} 409}
410 410
411static NORETURN void wait_for_child(HANDLE child)
412{
413 DWORD code;
414
415 SetConsoleCtrlHandler(NULL, TRUE);
416 WaitForSingleObject(child, INFINITE);
417 GetExitCodeProcess(child, &code);
418 exit((int)code);
419}
420
411int 421int
412mingw_execvp(const char *cmd, char *const *argv) 422mingw_execvp(const char *cmd, char *const *argv)
413{ 423{
414 int ret = (int)mingw_spawnvp(P_WAIT, cmd, argv); 424 intptr_t ret = mingw_spawnvp(P_NOWAIT, cmd, argv);
415 if (ret != -1 || errno == 0) 425 if (ret != -1 || errno == 0)
416 exit(ret); 426 wait_for_child((HANDLE)ret);
417 return ret; 427 return ret;
418} 428}
419 429
420int 430int
421mingw_execve(const char *cmd, char *const *argv, char *const *envp) 431mingw_execve(const char *cmd, char *const *argv, char *const *envp)
422{ 432{
423 int ret = (int)mingw_spawn_interpreter(P_WAIT, cmd, argv, envp, 0); 433 intptr_t ret = mingw_spawn_interpreter(P_NOWAIT, cmd, argv, envp, 0);
424 if (ret != -1 || errno == 0) 434 if (ret != -1 || errno == 0)
425 exit(ret); 435 wait_for_child((HANDLE)ret);
426 return ret; 436 return ret;
427} 437}
428 438