With FreeBSD 8.0 it seems like you can't block pending but undelivered signals

Jeremy Allison jra at samba.org
Fri Jan 11 18:24:05 MST 2013


On Wed, Jan 09, 2013 at 10:04:09AM -0800, Richard Sharpe wrote:
> On Wed, Jan 9, 2013 at 8:59 AM, Jeremy Allison <jra at samba.org> wrote:
> > On Wed, Jan 09, 2013 at 06:28:20AM -0800, Richard Sharpe wrote:
> >
> >
> > Cool ! Let's work on getting a portable tested fix into tevent !
> 
> OK, so we could test for the existence of ucontext_t as well as
> SA_SIGINFO and only allow such signal handling if both exist.
> 
> Ie, HAVE_UCONTEXT_T
> 
> Linux has it, as does FreeBSD and I am told that Solaris has it.
> 
> I wonder what other versions of UNIX have?

Once we detect HAVE_UCONTEXT_T in tevent then I think
this is the correct patch.

Jeremy.
-------------- next part --------------
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index 77ef7b0..4be54f2 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 hander, 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]);
 	}
 }


More information about the samba-technical mailing list