summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2013-02-23 22:50:57 +0000
committerjilles <jilles@FreeBSD.org>2013-02-23 22:50:57 +0000
commit6d26f3b024394ea5908af3fa212793fa333a2fdf (patch)
tree96a8314009f5f8c2883aef886d308ca958d3405c
parenta615230e591865d556975a47a4dc7d5cefbf4ebd (diff)
downloadFreeBSD-src-6d26f3b024394ea5908af3fa212793fa333a2fdf.zip
FreeBSD-src-6d26f3b024394ea5908af3fa212793fa333a2fdf.tar.gz
sh: If a SIGINT or SIGQUIT interrupts "wait", return status 128+sig.
-rw-r--r--bin/sh/eval.c2
-rw-r--r--bin/sh/jobs.c2
-rw-r--r--bin/sh/main.c2
-rw-r--r--bin/sh/trap.c35
-rw-r--r--bin/sh/trap.h2
-rw-r--r--tools/regression/bin/sh/builtins/wait4.012
-rw-r--r--tools/regression/bin/sh/builtins/wait5.012
7 files changed, 47 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;
diff --git a/tools/regression/bin/sh/builtins/wait4.0 b/tools/regression/bin/sh/builtins/wait4.0
new file mode 100644
index 0000000..7935131
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/wait4.0
@@ -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" ]
diff --git a/tools/regression/bin/sh/builtins/wait5.0 b/tools/regression/bin/sh/builtins/wait5.0
new file mode 100644
index 0000000..6874bf6
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/wait5.0
@@ -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" ]
OpenPOWER on IntegriCloud