sh: If a SIGINT or SIGQUIT interrupts "wait", return status 128+sig.
This commit is contained in:
parent
b2a67e7b16
commit
25e0f0f577
@ -301,7 +301,7 @@ evaltree(union node *n, int flags)
|
||||
} while (n != NULL);
|
||||
out:
|
||||
popstackmark(&smark);
|
||||
if (pendingsigs)
|
||||
if (pendingsig)
|
||||
dotrap();
|
||||
if (eflag && exitstatus != 0 && do_etest)
|
||||
exitshell(exitstatus);
|
||||
|
@ -521,7 +521,7 @@ waitcmd(int argc, char **argv)
|
||||
} while (dowait(DOWAIT_BLOCK | DOWAIT_SIG, (struct job *)NULL) != -1);
|
||||
in_waitcmd--;
|
||||
|
||||
return 0;
|
||||
return pendingsig + 128;
|
||||
}
|
||||
|
||||
|
||||
|
@ -196,7 +196,7 @@ cmdloop(int top)
|
||||
TRACE(("cmdloop(%d) called\n", top));
|
||||
setstackmark(&smark);
|
||||
for (;;) {
|
||||
if (pendingsigs)
|
||||
if (pendingsig)
|
||||
dotrap();
|
||||
inter = 0;
|
||||
if (iflag && top) {
|
||||
|
@ -73,7 +73,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
MKINIT char sigmode[NSIG]; /* current value of signal */
|
||||
int pendingsigs; /* indicates some signal received */
|
||||
volatile sig_atomic_t pendingsig; /* indicates some signal received */
|
||||
int in_dotrap; /* do we execute in a trap handler? */
|
||||
static char *volatile trap[NSIG]; /* trap handler commands */
|
||||
static volatile sig_atomic_t gotsig[NSIG];
|
||||
@ -388,22 +388,25 @@ onsig(int signo)
|
||||
return;
|
||||
}
|
||||
|
||||
if (signo != SIGCHLD || !ignore_sigchld)
|
||||
gotsig[signo] = 1;
|
||||
pendingsigs++;
|
||||
|
||||
/* If we are currently in a wait builtin, prepare to break it */
|
||||
if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0)
|
||||
breakwaitcmd = 1;
|
||||
/*
|
||||
* If a trap is set, not ignored and not the null command, we need
|
||||
* to make sure traps are executed even when a child blocks signals.
|
||||
*/
|
||||
if (Tflag &&
|
||||
trap[signo] != NULL &&
|
||||
! (trap[signo][0] == '\0') &&
|
||||
! (trap[signo][0] == ':' && trap[signo][1] == '\0'))
|
||||
if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0) {
|
||||
breakwaitcmd = 1;
|
||||
pendingsig = signo;
|
||||
}
|
||||
|
||||
if (trap[signo] != NULL && trap[signo][0] != '\0' &&
|
||||
(signo != SIGCHLD || !ignore_sigchld)) {
|
||||
gotsig[signo] = 1;
|
||||
pendingsig = signo;
|
||||
|
||||
/*
|
||||
* If a trap is set, not ignored and not the null command, we
|
||||
* need to make sure traps are executed even when a child
|
||||
* blocks signals.
|
||||
*/
|
||||
if (Tflag && !(trap[signo][0] == ':' && trap[signo][1] == '\0'))
|
||||
breakwaitcmd = 1;
|
||||
}
|
||||
|
||||
#ifndef NO_HISTORY
|
||||
if (signo == SIGWINCH)
|
||||
@ -424,7 +427,7 @@ dotrap(void)
|
||||
|
||||
in_dotrap++;
|
||||
for (;;) {
|
||||
pendingsigs = 0;
|
||||
pendingsig = 0;
|
||||
for (i = 1; i < NSIG; i++) {
|
||||
if (gotsig[i]) {
|
||||
gotsig[i] = 0;
|
||||
|
@ -33,7 +33,7 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
extern int pendingsigs;
|
||||
extern volatile sig_atomic_t pendingsig;
|
||||
extern int in_dotrap;
|
||||
extern volatile sig_atomic_t gotwinch;
|
||||
|
||||
|
12
tools/regression/bin/sh/builtins/wait4.0
Normal file
12
tools/regression/bin/sh/builtins/wait4.0
Normal file
@ -0,0 +1,12 @@
|
||||
# $FreeBSD$
|
||||
|
||||
T=`mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX`
|
||||
trap 'rm -rf $T' 0
|
||||
cd $T || exit 3
|
||||
mkfifo fifo1
|
||||
trapped=
|
||||
trap trapped=1 QUIT
|
||||
{ kill -QUIT $$; sleep 1; exit 4; } >fifo1 &
|
||||
wait $! <fifo1
|
||||
r=$?
|
||||
[ "$r" -gt 128 ] && [ -n "$trapped" ]
|
12
tools/regression/bin/sh/builtins/wait5.0
Normal file
12
tools/regression/bin/sh/builtins/wait5.0
Normal file
@ -0,0 +1,12 @@
|
||||
# $FreeBSD$
|
||||
|
||||
T=`mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX`
|
||||
trap 'rm -rf $T' 0
|
||||
cd $T || exit 3
|
||||
mkfifo fifo1
|
||||
trapped=
|
||||
trap trapped=1 QUIT
|
||||
{ kill -QUIT $$; sleep 1; exit 4; } >fifo1 &
|
||||
wait <fifo1
|
||||
r=$?
|
||||
[ "$r" -gt 128 ] && [ -n "$trapped" ]
|
Loading…
Reference in New Issue
Block a user