diff options
Diffstat (limited to 'win32')
-rw-r--r-- | win32/process.c | 37 | ||||
-rw-r--r-- | win32/system.c | 7 |
2 files changed, 36 insertions, 8 deletions
diff --git a/win32/process.c b/win32/process.c index 2f8b6ce31..54d98e1d9 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -45,7 +45,7 @@ pid_t mingw_wait3(pid_t pid, int *status, int options, struct rusage *rusage) | |||
45 | } | 45 | } |
46 | #endif | 46 | #endif |
47 | CloseHandle(proc); | 47 | CloseHandle(proc); |
48 | *status = code << 8; | 48 | *status = exit_code_to_wait_status(code); |
49 | return pid; | 49 | return pid; |
50 | } | 50 | } |
51 | } | 51 | } |
@@ -407,7 +407,7 @@ static NORETURN void wait_for_child(HANDLE child) | |||
407 | SetConsoleCtrlHandler(kill_child_ctrl_handler, TRUE); | 407 | SetConsoleCtrlHandler(kill_child_ctrl_handler, TRUE); |
408 | WaitForSingleObject(child, INFINITE); | 408 | WaitForSingleObject(child, INFINITE); |
409 | GetExitCodeProcess(child, &code); | 409 | GetExitCodeProcess(child, &code); |
410 | exit((int)code); | 410 | exit(exit_code_to_posix(code)); |
411 | } | 411 | } |
412 | 412 | ||
413 | int | 413 | int |
@@ -807,6 +807,39 @@ int FAST_FUNC is_valid_signal(int number) | |||
807 | return isalpha(*get_signame(number)); | 807 | return isalpha(*get_signame(number)); |
808 | } | 808 | } |
809 | 809 | ||
810 | int exit_code_to_wait_status(DWORD exit_code) | ||
811 | { | ||
812 | int sig, status; | ||
813 | |||
814 | if (exit_code == 0xc0000005) | ||
815 | return SIGSEGV; | ||
816 | else if (exit_code == 0xc000013a) | ||
817 | return SIGINT; | ||
818 | |||
819 | // When a process is terminated as if by a signal the Windows | ||
820 | // exit code is zero apart from the signal in its topmost byte. | ||
821 | // This is a busybox-w32 convention. | ||
822 | sig = exit_code >> 24; | ||
823 | if (sig != 0 && exit_code == sig << 24 && is_valid_signal(sig)) | ||
824 | return sig; | ||
825 | |||
826 | // Use least significant byte as exit code, but not if it's zero | ||
827 | // and the Windows exit code as a whole is non-zero. | ||
828 | status = exit_code & 0xff; | ||
829 | if (exit_code != 0 && status == 0) | ||
830 | status = 255; | ||
831 | return status << 8; | ||
832 | } | ||
833 | |||
834 | int exit_code_to_posix(DWORD exit_code) | ||
835 | { | ||
836 | int status = exit_code_to_wait_status(exit_code); | ||
837 | |||
838 | if (WIFSIGNALED(status)) | ||
839 | return 128 + WTERMSIG(status); | ||
840 | return WEXITSTATUS(status); | ||
841 | } | ||
842 | |||
810 | int kill(pid_t pid, int sig) | 843 | int kill(pid_t pid, int sig) |
811 | { | 844 | { |
812 | if (sig == SIGKILL || sig == 0) | 845 | if (sig == SIGKILL || sig == 0) |
diff --git a/win32/system.c b/win32/system.c index 00b594242..c718d9948 100644 --- a/win32/system.c +++ b/win32/system.c | |||
@@ -6,7 +6,6 @@ int mingw_system(const char *cmd) | |||
6 | intptr_t proc; | 6 | intptr_t proc; |
7 | HANDLE h; | 7 | HANDLE h; |
8 | DWORD ret = 0; | 8 | DWORD ret = 0; |
9 | int sig; | ||
10 | 9 | ||
11 | if (cmd == NULL) | 10 | if (cmd == NULL) |
12 | return 1; | 11 | return 1; |
@@ -19,9 +18,5 @@ int mingw_system(const char *cmd) | |||
19 | GetExitCodeProcess(h, &ret); | 18 | GetExitCodeProcess(h, &ret); |
20 | CloseHandle(h); | 19 | CloseHandle(h); |
21 | 20 | ||
22 | // Was process terminated as if by a signal? | 21 | return exit_code_to_wait_status(ret); |
23 | sig = ret >> 24; | ||
24 | if (sig != 0 && ret == sig << 24 && is_valid_signal(sig)) | ||
25 | return sig; | ||
26 | return ret << 8; | ||
27 | } | 22 | } |