aboutsummaryrefslogtreecommitdiff
path: root/win32/process.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-10-11 15:58:14 +0100
committerRon Yorston <rmy@pobox.com>2024-10-11 16:24:48 +0100
commit4bdeee55c1c2a456cae12abdff775fc60903bd6f (patch)
tree81e575aa73c7059cb673f52716284692ada2974c /win32/process.c
parentf84964d647e3a58905f5692dfdb9319dc170bb88 (diff)
downloadbusybox-w32-4bdeee55c1c2a456cae12abdff775fc60903bd6f.tar.gz
busybox-w32-4bdeee55c1c2a456cae12abdff775fc60903bd6f.tar.bz2
busybox-w32-4bdeee55c1c2a456cae12abdff775fc60903bd6f.zip
win32: fix problem interrupting shell loop
It proved to be almost impossible to interrupt a loop like: while true; do sleep 1; done where 'sleep' was an external program, not an applet. The issue was introduced by commit 0475b7a64 (win32: convert exit codes). This passed a POSIX error code to the exit() in wait_for_child() so a parent was unable to detect when its child was interrupted. Pass the Windows exit code to exit() instead. Work around the changes introduced by commit 790e377273 (win32: revert 'don't set error mode'). Adds 16-32 bytes.
Diffstat (limited to '')
-rw-r--r--win32/process.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/win32/process.c b/win32/process.c
index 9a5ab417a..34ef3cffa 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -482,24 +482,22 @@ static int exit_code_to_wait_status_cmd(DWORD exit_code, const char *cmd)
482 return status << 8; 482 return status << 8;
483} 483}
484 484
485static int exit_code_to_posix_cmd(DWORD exit_code, const char *cmd)
486{
487 int status = exit_code_to_wait_status_cmd(exit_code, cmd);
488
489 if (WIFSIGNALED(status))
490 return 128 + WTERMSIG(status);
491 return WEXITSTATUS(status);
492}
493
494static NORETURN void wait_for_child(HANDLE child, const char *cmd) 485static NORETURN void wait_for_child(HANDLE child, const char *cmd)
495{ 486{
496 DWORD code; 487 DWORD code;
488 int status;
497 489
498 kill_child_ctrl_handler(GetProcessId(child)); 490 kill_child_ctrl_handler(GetProcessId(child));
499 SetConsoleCtrlHandler(kill_child_ctrl_handler, TRUE); 491 SetConsoleCtrlHandler(kill_child_ctrl_handler, TRUE);
500 WaitForSingleObject(child, INFINITE); 492 WaitForSingleObject(child, INFINITE);
501 GetExitCodeProcess(child, &code); 493 GetExitCodeProcess(child, &code);
502 exit(exit_code_to_posix_cmd(code, cmd)); 494 // We don't need the wait status, but get it anyway so the error
495 // message can include the command. In such cases we pass the
496 // exit status to exit() so our caller won't repeat the message.
497 status = exit_code_to_wait_status_cmd(code, cmd);
498 if (!WIFSIGNALED(status) && code > 0xff)
499 code = WEXITSTATUS(status);
500 exit((int)code);
503} 501}
504 502
505int 503int
@@ -949,5 +947,9 @@ int exit_code_to_wait_status(DWORD exit_code)
949 947
950int exit_code_to_posix(DWORD exit_code) 948int exit_code_to_posix(DWORD exit_code)
951{ 949{
952 return exit_code_to_posix_cmd(exit_code, NULL); 950 int status = exit_code_to_wait_status(exit_code);
951
952 if (WIFSIGNALED(status))
953 return 128 + WTERMSIG(status);
954 return WEXITSTATUS(status);
953} 955}