summaryrefslogtreecommitdiff
path: root/Src/signals.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/signals.c')
-rw-r--r--Src/signals.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/Src/signals.c b/Src/signals.c
index 0b508f869..3abeab647 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -347,9 +347,38 @@ static int suspend_longjmp = 0;
static signal_jmp_buf suspend_jmp_buf;
#endif
+#if defined(POSIX_SIGNALS) || defined(BSD_SIGNALS)
+static void
+signal_suspend_setup(sigset_t *set, int sig, int wait_cmd)
+{
+ if (isset(TRAPSASYNC)) {
+ sigemptyset(set);
+ } else {
+ sigfillset(set);
+ sigdelset(set, sig);
+#ifdef POSIX_SIGNALS
+ sigdelset(set, SIGHUP); /* still don't know why we add this? */
+#endif
+ if (wait_cmd)
+ {
+ /*
+ * Using "wait" builtin. We should allow SIGINT and
+ * execute traps delivered to the shell.
+ */
+ int sigtr;
+ sigdelset(set, SIGINT);
+ for (sigtr = 1; sigtr <= NSIG; sigtr++) {
+ if (sigtrapped[sigtr] & ~ZSIG_IGNORED)
+ sigdelset(set, sigtr);
+ }
+ }
+ }
+}
+#endif
+
/**/
int
-signal_suspend(int sig, int sig2)
+signal_suspend(int sig, int wait_cmd)
{
int ret;
@@ -359,15 +388,7 @@ signal_suspend(int sig, int sig2)
sigset_t oset;
#endif /* BROKEN_POSIX_SIGSUSPEND */
- if (isset(TRAPSASYNC)) {
- sigemptyset(&set);
- } else {
- sigfillset(&set);
- sigdelset(&set, sig);
- sigdelset(&set, SIGHUP); /* still don't know why we add this? */
- if (sig2)
- sigdelset(&set, sig2);
- }
+ signal_suspend_setup(&set, sig, wait_cmd);
#ifdef BROKEN_POSIX_SIGSUSPEND
sigprocmask(SIG_SETMASK, &set, &oset);
pause();
@@ -379,15 +400,8 @@ signal_suspend(int sig, int sig2)
# ifdef BSD_SIGNALS
sigset_t set;
- if (isset(TRAPSASYNC)) {
- sigemptyset(&set);
- } else {
- sigfillset(&set);
- sigdelset(&set, sig);
- if (sig2)
- sigdelset(&set, sig2);
- ret = sigpause(set);
- }
+ signal_suspend_setup(&set, sig, wait_cmd);
+ ret = sigpause(set);
# else
# ifdef SYSV_SIGNALS
ret = sigpause(sig);
@@ -397,7 +411,7 @@ signal_suspend(int sig, int sig2)
* between the child_unblock() and pause() */
if (signal_setjmp(suspend_jmp_buf) == 0) {
suspend_longjmp = 1; /* we want to signal_longjmp after catching signal */
- child_unblock(); /* do we need to unblock sig2 as well? */
+ child_unblock(); /* do we need to do wait_cmd stuff as well? */
ret = pause();
}
suspend_longjmp = 0; /* turn off using signal_longjmp since we are past *
@@ -409,6 +423,10 @@ signal_suspend(int sig, int sig2)
return ret;
}
+/* last signal we handled: race prone, or what? */
+/**/
+int last_signal;
+
/* the signal handler */
/**/
@@ -422,6 +440,7 @@ zhandler(int sig)
signal_jmp_buf jump_to;
#endif
+ last_signal = sig;
signal_process(sig);
sigfillset(&newmask);