summaryrefslogtreecommitdiffstats
path: root/signal.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-09-06 22:40:19 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-09-06 22:40:19 -0700
commitded0935f38e13b0b211c6a365277b26241325446 (patch)
tree1b580fc33d4bedd8c7efea82a06165d3505c99b4 /signal.c
parent2b77a3696e74eb9e0414bd3895fa6352f4572f25 (diff)
downloadtxr-ded0935f38e13b0b211c6a365277b26241325446.tar.gz
txr-ded0935f38e13b0b211c6a365277b26241325446.tar.bz2
txr-ded0935f38e13b0b211c6a365277b26241325446.zip
Bugfix: sig_mask not calling into the OS.
This is just amazingly broken; sig_mask recurses instead of calling sigprocmask. Also, we need a way to reload the signal mask cache from the kernel, because the kernel can change the signal mask behind our back. * signal.c (sig_reload_cache): New static function. (sig_handler): Call sig_reload_cache to ensure the sig_blocked_cache accurately reflects the currently blocked signal set. (sig_init): Call sig_reload_cache at init time to correctly reflect any blocked signals. (sig_mask): Call sigprocmask instead of recursing. Moreover, the correct op code is SIG_SETMASK, not SIG_BLOCK.
Diffstat (limited to 'signal.c')
-rw-r--r--signal.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/signal.c b/signal.c
index 299dd215..9b9abffd 100644
--- a/signal.c
+++ b/signal.c
@@ -64,6 +64,11 @@ static int is_cpu_exception(int sig)
}
}
+static int sig_reload_cache(void)
+{
+ return sigprocmask(SIG_BLOCK, 0, &sig_blocked_cache);
+}
+
static void sig_handler(int sig)
{
val lambda = sig_lambda[sig];
@@ -78,6 +83,8 @@ static void sig_handler(int sig)
async_sig_enabled = 1;
}
+ sig_reload_cache();
+
if (lambda) {
if (!in_interrupt && async_sig_enabled) {
async_sig_enabled = 0;
@@ -175,6 +182,8 @@ void sig_init(void)
reg_fun(intern(lit("get-sig-handler"), user_package), func_n1(get_sig_handler));
reg_fun(intern(lit("sig-check"), user_package), func_n0(sig_check));
reg_fun(intern(lit("kill"), user_package), func_n2o(kill_wrap, 1));
+
+ sig_reload_cache();
}
#if HAVE_SIGALTSTACK
@@ -340,7 +349,7 @@ int sig_mask(int how, const sigset_t *set, sigset_t *oldset)
if (memcmp(&sig_blocked_cache, pnew, sizeof *pnew) != 0) {
sig_blocked_cache = *pnew;
- return sig_mask(SIG_BLOCK, pnew, oldset);
+ return sigprocmask(SIG_SETMASK, &sig_blocked_cache, oldset);
}
if (oldset != 0)