tevent: Fix bug 9550 - sigprocmask does not work on FreeBSD to stop further signals...
authorJeremy Allison <jra@samba.org>
Mon, 14 Jan 2013 23:22:11 +0000 (15:22 -0800)
committerStefan Metzmacher <metze@samba.org>
Tue, 15 Jan 2013 11:13:43 +0000 (12:13 +0100)
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

lib/tevent/tevent_signal.c

index 77ef7b0599a532af4cfa3786d6fd4c3403c8d68b..9582f6e7acdcb566b80c9f396335c64fb1598ac7 100644 (file)
@@ -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]);
        }
 }