diff options
author | jilles <jilles@FreeBSD.org> | 2013-02-23 22:50:57 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2013-02-23 22:50:57 +0000 |
commit | 6d26f3b024394ea5908af3fa212793fa333a2fdf (patch) | |
tree | 96a8314009f5f8c2883aef886d308ca958d3405c /bin | |
parent | a615230e591865d556975a47a4dc7d5cefbf4ebd (diff) | |
download | FreeBSD-src-6d26f3b024394ea5908af3fa212793fa333a2fdf.zip FreeBSD-src-6d26f3b024394ea5908af3fa212793fa333a2fdf.tar.gz |
sh: If a SIGINT or SIGQUIT interrupts "wait", return status 128+sig.
Diffstat (limited to 'bin')
-rw-r--r-- | bin/sh/eval.c | 2 | ||||
-rw-r--r-- | bin/sh/jobs.c | 2 | ||||
-rw-r--r-- | bin/sh/main.c | 2 | ||||
-rw-r--r-- | bin/sh/trap.c | 35 | ||||
-rw-r--r-- | bin/sh/trap.h | 2 |
5 files changed, 23 insertions, 20 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c index b40fffd..0972b10 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -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); diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c index c86394f..5a2790b 100644 --- a/bin/sh/jobs.c +++ b/bin/sh/jobs.c @@ -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; } diff --git a/bin/sh/main.c b/bin/sh/main.c index 66e1335..5dc050f 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -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) { diff --git a/bin/sh/trap.c b/bin/sh/trap.c index 521c511..0a9eb60 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -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; diff --git a/bin/sh/trap.h b/bin/sh/trap.h index 61a17ec..0a05d8d 100644 --- a/bin/sh/trap.h +++ b/bin/sh/trap.h @@ -33,7 +33,7 @@ * $FreeBSD$ */ -extern int pendingsigs; +extern volatile sig_atomic_t pendingsig; extern int in_dotrap; extern volatile sig_atomic_t gotwinch; |