aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/process.c37
-rw-r--r--win32/system.c7
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
413int 413int
@@ -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
810int 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
834int 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
810int kill(pid_t pid, int sig) 843int 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}