aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-05-23 10:57:56 +0100
committerRon Yorston <rmy@pobox.com>2023-05-23 10:57:56 +0100
commit89aa9d783c535670c6aed1d32c8740b7474cca00 (patch)
tree52a494ad5f8a89fbdb5ad2a6155a62d7d3a6a024 /shell
parentc2c0cfbeb6f07fa3257a60760d5c8a5382cee6e9 (diff)
downloadbusybox-w32-89aa9d783c535670c6aed1d32c8740b7474cca00.tar.gz
busybox-w32-89aa9d783c535670c6aed1d32c8740b7474cca00.tar.bz2
busybox-w32-89aa9d783c535670c6aed1d32c8740b7474cca00.zip
win32: changes to signal handling
Use an exit code of the form (signal << 24) when a process exits due to a signal. This replaces the previous use of (signal + 128). This makes it easier to distinguish exit codes from signals. Allow kill(2) to handle all defined signals, not just EXIT, TERM and KILL. The kill and timeout applets now accept any defined signals. Convert certain Windows status codes Unix-style signal codes. In ash: - Exit as if with SIGINT in raise_interrupt() rather than call raise(SIGINT). The latter returns an exit code of 3. - Detect if a child process exits as if with SIGINT. If not and if the parent is an interactive top-level shell, reset pending_int. This prevents the parent from seeing an INT if the child hasn't reported it exited due to INT. (Probably due to it being an interactive shell.) Costs 132-136 bytes.
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c31
1 files changed, 25 insertions, 6 deletions
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);