diff options
author | Ron Yorston <rmy@pobox.com> | 2023-04-05 09:32:42 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-04-05 09:32:42 +0100 |
commit | 9db9b34adaad1a9ebe892eaea486cfe0610bad8d (patch) | |
tree | ae7b191ef7421c861ce1ee96e2564f6ba3283c8b | |
parent | d4494ebdeb3340f98a7a79244601b5d574ae36d1 (diff) | |
download | busybox-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.c | 18 |
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 | ||
411 | static 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 | |||
411 | int | 421 | int |
412 | mingw_execvp(const char *cmd, char *const *argv) | 422 | mingw_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 | ||
420 | int | 430 | int |
421 | mingw_execve(const char *cmd, char *const *argv, char *const *envp) | 431 | mingw_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 | ||