aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/timeout.c4
-rw-r--r--findutils/xargs.c2
-rw-r--r--include/mingw.h3
-rw-r--r--shell/ash.c31
-rw-r--r--win32/process.c21
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;
54static void kill_child(void) 54static 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
543int kill_SIGTERM_by_handle(HANDLE process); 543int kill_signal_by_handle(HANDLE process, int sig);
544int 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 */
708int kill_SIGTERM_by_handle(HANDLE process) 708int 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
737static int kill_SIGTERM(pid_t pid, int sig UNUSED_PARAM) 737static 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
774int FAST_FUNC is_valid_signal(int number)
775{
776 return isalpha(*get_signame(number));
777}
778
774int kill(pid_t pid, int sig) 779int 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;