summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2013-01-14 15:22:11 -0800
committerStefan Metzmacher <metze@samba.org>2013-01-15 12:13:43 +0100
commit8f8ca589d2aa7f9deaae6a05cb5ab73da95372bf (patch)
tree059abcb7fad0a861b1e68c89b8fe48f85b6df7f0
parent0258138e207c8f3e8bb05a47599aa04b4e9567cf (diff)
downloadsamba-8f8ca589d2aa7f9deaae6a05cb5ab73da95372bf.tar.gz
samba-8f8ca589d2aa7f9deaae6a05cb5ab73da95372bf.tar.bz2
samba-8f8ca589d2aa7f9deaae6a05cb5ab73da95372bf.zip
tevent: Fix bug 9550 - sigprocmask does not work on FreeBSD to stop further signals in a signal handler
Mask off signals the correct way from the signal handler. Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org> Autobuild-User(master): Stefan Metzmacher <metze@samba.org> Autobuild-Date(master): Tue Jan 15 12:13:43 CET 2013 on sn-devel-104
-rw-r--r--lib/tevent/tevent_signal.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index 77ef7b0599..9582f6e7ac 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -121,10 +121,39 @@ static void tevent_common_signal_handler_info(int signum, siginfo_t *info,
if (count+1 == TEVENT_SA_INFO_QUEUE_COUNT) {
/* we've filled the info array - block this signal until
these ones are delivered */
+#ifdef HAVE_UCONTEXT_T
+ /*
+ * This is the only way for this to work.
+ * By default signum is blocked inside this
+ * signal handler using a temporary mask,
+ * but what we really need to do now is
+ * block it in the callers mask, so it
+ * stays blocked when the temporary signal
+ * handler mask is replaced when we return
+ * from here. The callers mask can be found
+ * in the ucontext_t passed in as the
+ * void *uctx argument.
+ */
+ ucontext_t *ucp = (ucontext_t *)uctx;
+ sigaddset(&ucp->uc_sigmask, signum);
+#else
+ /*
+ * WARNING !!! WARNING !!!!
+ *
+ * This code doesn't work.
+ * By default signum is blocked inside this
+ * signal handler, but calling sigprocmask
+ * modifies the temporary signal mask being
+ * used *inside* this handler, which will be
+ * replaced by the callers signal mask once
+ * we return from here. See Samba
+ * bug #9550 for details.
+ */
sigset_t set;
sigemptyset(&set);
sigaddset(&set, signum);
sigprocmask(SIG_BLOCK, &set, NULL);
+#endif
TEVENT_SIG_INCREMENT(sig_state->sig_blocked[signum]);
}
}