diff options
-rw-r--r-- | coreutils/timeout.c | 4 | ||||
-rw-r--r-- | findutils/xargs.c | 2 | ||||
-rw-r--r-- | include/mingw.h | 3 | ||||
-rw-r--r-- | shell/ash.c | 31 | ||||
-rw-r--r-- | win32/process.c | 21 |
5 files changed, 43 insertions, 18 deletions
diff --git a/coreutils/timeout.c b/coreutils/timeout.c index 3565c005d..8f306529f 100644 --- a/coreutils/timeout.c +++ b/coreutils/timeout.c | |||
@@ -54,7 +54,7 @@ static HANDLE child = INVALID_HANDLE_VALUE; | |||
54 | static void kill_child(void) | 54 | static void kill_child(void) |
55 | { | 55 | { |
56 | if (child != INVALID_HANDLE_VALUE) { | 56 | if (child != INVALID_HANDLE_VALUE) { |
57 | kill_SIGTERM_by_handle(child); | 57 | kill_signal_by_handle(child, SIGTERM); |
58 | } | 58 | } |
59 | } | 59 | } |
60 | 60 | ||
@@ -130,7 +130,7 @@ int timeout_main(int argc UNUSED_PARAM, char **argv) | |||
130 | #if !ENABLE_PLATFORM_MINGW32 | 130 | #if !ENABLE_PLATFORM_MINGW32 |
131 | if (signo < 0) | 131 | if (signo < 0) |
132 | #else | 132 | #else |
133 | if (signo != SIGTERM && signo != SIGKILL && signo != 0) | 133 | if (!is_valid_signal(signo)) |
134 | #endif | 134 | #endif |
135 | bb_error_msg_and_die("unknown signal '%s'", opt_s); | 135 | bb_error_msg_and_die("unknown signal '%s'", opt_s); |
136 | 136 | ||
diff --git a/findutils/xargs.c b/findutils/xargs.c index bc47a869f..1e7d8de02 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
@@ -216,7 +216,7 @@ static BOOL WINAPI ctrl_handler(DWORD dwCtrlType) | |||
216 | } | 216 | } |
217 | } | 217 | } |
218 | # endif | 218 | # endif |
219 | exit(128 + SIGINT); | 219 | exit(SIGINT << 24); |
220 | return TRUE; | 220 | return TRUE; |
221 | } | 221 | } |
222 | return FALSE; | 222 | return FALSE; |
diff --git a/include/mingw.h b/include/mingw.h index 6204ded6d..f94804d91 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -540,7 +540,8 @@ int mingw_execve(const char *cmd, char *const *argv, char *const *envp); | |||
540 | 540 | ||
541 | #define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':') | 541 | #define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':') |
542 | 542 | ||
543 | int kill_SIGTERM_by_handle(HANDLE process); | 543 | int kill_signal_by_handle(HANDLE process, int sig); |
544 | int FAST_FUNC is_valid_signal(int number); | ||
544 | 545 | ||
545 | #define find_mount_point(n, s) find_mount_point(n) | 546 | #define find_mount_point(n, s) find_mount_point(n) |
546 | 547 | ||
diff --git a/shell/ash.c b/shell/ash.c index 93c402a8b..87df555dd 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -884,9 +884,13 @@ raise_interrupt(void) | |||
884 | /* pending_sig = 0; - now done in signal_handler() */ | 884 | /* pending_sig = 0; - now done in signal_handler() */ |
885 | 885 | ||
886 | if (!(rootshell && iflag)) { | 886 | if (!(rootshell && iflag)) { |
887 | #if !ENABLE_PLATFORM_MINGW32 | ||
887 | /* Kill ourself with SIGINT */ | 888 | /* Kill ourself with SIGINT */ |
888 | signal(SIGINT, SIG_DFL); | 889 | signal(SIGINT, SIG_DFL); |
889 | raise(SIGINT); | 890 | raise(SIGINT); |
891 | #else | ||
892 | exit(SIGINT << 24); | ||
893 | #endif | ||
890 | } | 894 | } |
891 | #if ENABLE_PLATFORM_MINGW32 | 895 | #if ENABLE_PLATFORM_MINGW32 |
892 | if (iflag) | 896 | if (iflag) |
@@ -4122,8 +4126,10 @@ struct job { | |||
4122 | #define JOBDONE 2 /* all procs are completed */ | 4126 | #define JOBDONE 2 /* all procs are completed */ |
4123 | unsigned | 4127 | unsigned |
4124 | state: 8, | 4128 | state: 8, |
4125 | #if JOBS | 4129 | #if JOBS || ENABLE_PLATFORM_MINGW32 |
4126 | sigint: 1, /* job was killed by SIGINT */ | 4130 | sigint: 1, /* job was killed by SIGINT */ |
4131 | #endif | ||
4132 | #if JOBS | ||
4127 | jobctl: 1, /* job running under job control */ | 4133 | jobctl: 1, /* job running under job control */ |
4128 | #endif | 4134 | #endif |
4129 | waited: 1, /* true if this entry has been waited for */ | 4135 | waited: 1, /* true if this entry has been waited for */ |
@@ -4840,7 +4846,7 @@ waitpid_child(int *status, int wait_flags) | |||
4840 | HANDLE *proclist; | 4846 | HANDLE *proclist; |
4841 | pid_t pid = -1; | 4847 | pid_t pid = -1; |
4842 | DWORD win_status, idx; | 4848 | DWORD win_status, idx; |
4843 | int i; | 4849 | int i, sig; |
4844 | 4850 | ||
4845 | for (jb = curjob; jb; jb = jb->prev_job) { | 4851 | for (jb = curjob; jb; jb = jb->prev_job) { |
4846 | if (jb->state != JOBDONE) | 4852 | if (jb->state != JOBDONE) |
@@ -4872,9 +4878,18 @@ waitpid_child(int *status, int wait_flags) | |||
4872 | wait_flags&WNOHANG ? 1 : INFINITE); | 4878 | wait_flags&WNOHANG ? 1 : INFINITE); |
4873 | if (idx < pid_nr) { | 4879 | if (idx < pid_nr) { |
4874 | GetExitCodeProcess(proclist[idx], &win_status); | 4880 | GetExitCodeProcess(proclist[idx], &win_status); |
4875 | *status = (int)win_status << 8; | 4881 | if (win_status == 0xc0000005) |
4876 | if (win_status == 128 + SIGTERM || win_status == 128 + SIGKILL) | 4882 | win_status = SIGSEGV << 24; |
4877 | *status += win_status - 128; | 4883 | else if (win_status == 0xc000013a) |
4884 | win_status = SIGINT << 24; | ||
4885 | |||
4886 | // When a process is terminated as if by a signal the exit | ||
4887 | // code is zero apart from the signal in its topmost byte. | ||
4888 | sig = win_status >> 24; | ||
4889 | if (sig != 0 && win_status == sig << 24 && is_valid_signal(sig)) | ||
4890 | *status = sig; | ||
4891 | else | ||
4892 | *status = (int)win_status << 8; | ||
4878 | pid = pidlist[idx]; | 4893 | pid = pidlist[idx]; |
4879 | } | 4894 | } |
4880 | done: | 4895 | done: |
@@ -5241,7 +5256,7 @@ getstatus(struct job *job) | |||
5241 | { | 5256 | { |
5242 | /* XXX: limits number of signals */ | 5257 | /* XXX: limits number of signals */ |
5243 | retval = WTERMSIG(status); | 5258 | retval = WTERMSIG(status); |
5244 | #if JOBS | 5259 | #if JOBS || ENABLE_PLATFORM_MINGW32 |
5245 | if (retval == SIGINT) | 5260 | if (retval == SIGINT) |
5246 | job->sigint = 1; | 5261 | job->sigint = 1; |
5247 | #endif | 5262 | #endif |
@@ -6051,6 +6066,10 @@ waitforjob(struct job *jp) | |||
6051 | return exitstatus; | 6066 | return exitstatus; |
6052 | 6067 | ||
6053 | st = getstatus(jp); | 6068 | st = getstatus(jp); |
6069 | #if ENABLE_PLATFORM_MINGW32 | ||
6070 | if (!jp->sigint && iflag && rootshell) | ||
6071 | pending_int = 0; | ||
6072 | #endif | ||
6054 | #if JOBS | 6073 | #if JOBS |
6055 | if (jp->jobctl) { | 6074 | if (jp->jobctl) { |
6056 | xtcsetpgrp(ttyfd, rootpid); | 6075 | xtcsetpgrp(ttyfd, rootpid); |
diff --git a/win32/process.c b/win32/process.c index 228b0b30e..ebc006d4e 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -705,14 +705,14 @@ static inline int process_architecture_matches_current(HANDLE process) | |||
705 | * http://www.drdobbs.com/a-safer-alternative-to-terminateprocess/184416547 | 705 | * http://www.drdobbs.com/a-safer-alternative-to-terminateprocess/184416547 |
706 | * | 706 | * |
707 | */ | 707 | */ |
708 | int kill_SIGTERM_by_handle(HANDLE process) | 708 | int kill_signal_by_handle(HANDLE process, int sig) |
709 | { | 709 | { |
710 | DWORD code; | 710 | DWORD code; |
711 | int ret = 0; | 711 | int ret = 0; |
712 | 712 | ||
713 | if (GetExitCodeProcess(process, &code) && code == STILL_ACTIVE) { | 713 | if (GetExitCodeProcess(process, &code) && code == STILL_ACTIVE) { |
714 | DECLARE_PROC_ADDR(DWORD, ExitProcess, LPVOID); | 714 | DECLARE_PROC_ADDR(DWORD, ExitProcess, LPVOID); |
715 | PVOID arg = (PVOID)(intptr_t)(128 + SIGTERM); | 715 | PVOID arg = (PVOID)(intptr_t)(sig << 24); |
716 | DWORD thread_id; | 716 | DWORD thread_id; |
717 | HANDLE thread; | 717 | HANDLE thread; |
718 | 718 | ||
@@ -734,7 +734,7 @@ int kill_SIGTERM_by_handle(HANDLE process) | |||
734 | return ret; | 734 | return ret; |
735 | } | 735 | } |
736 | 736 | ||
737 | static int kill_SIGTERM(pid_t pid, int sig UNUSED_PARAM) | 737 | static int kill_signal(pid_t pid, int sig) |
738 | { | 738 | { |
739 | HANDLE process; | 739 | HANDLE process; |
740 | 740 | ||
@@ -745,7 +745,7 @@ static int kill_SIGTERM(pid_t pid, int sig UNUSED_PARAM) | |||
745 | return -1; | 745 | return -1; |
746 | } | 746 | } |
747 | 747 | ||
748 | return kill_SIGTERM_by_handle(process); | 748 | return kill_signal_by_handle(process, sig); |
749 | } | 749 | } |
750 | 750 | ||
751 | /* | 751 | /* |
@@ -765,18 +765,23 @@ static int kill_SIGKILL(pid_t pid, int sig) | |||
765 | } | 765 | } |
766 | 766 | ||
767 | if (sig == SIGKILL) | 767 | if (sig == SIGKILL) |
768 | ret = !TerminateProcess(process, 128 + SIGKILL); | 768 | ret = !TerminateProcess(process, SIGKILL << 24); |
769 | CloseHandle(process); | 769 | CloseHandle(process); |
770 | 770 | ||
771 | return ret; | 771 | return ret; |
772 | } | 772 | } |
773 | 773 | ||
774 | int FAST_FUNC is_valid_signal(int number) | ||
775 | { | ||
776 | return isalpha(*get_signame(number)); | ||
777 | } | ||
778 | |||
774 | int kill(pid_t pid, int sig) | 779 | int kill(pid_t pid, int sig) |
775 | { | 780 | { |
776 | if (sig == SIGTERM) | 781 | if (sig == SIGKILL || sig == 0) |
777 | return kill_pids(pid, sig, kill_SIGTERM); | ||
778 | else if (sig == SIGKILL || sig == 0) | ||
779 | return kill_pids(pid, sig, kill_SIGKILL); | 782 | return kill_pids(pid, sig, kill_SIGKILL); |
783 | else if (is_valid_signal(sig)) | ||
784 | return kill_pids(pid, sig, kill_signal); | ||
780 | 785 | ||
781 | errno = EINVAL; | 786 | errno = EINVAL; |
782 | return -1; | 787 | return -1; |