From ded0935f38e13b0b211c6a365277b26241325446 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 6 Sep 2015 22:40:19 -0700 Subject: 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. --- signal.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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) -- cgit v1.2.3