On Tue, 8 Jan 2013, Richard Sharpe wrote:

[ ... ]

Well, it turns out that your suggestion was correct.

I did some more searching and found another similar suggestion, so I
gave it a whirl, and it works.

Now, my problem is that Jeremy Allison thinks that it is a fugly hack.
This means that I will probably have big problems getting a patch for
this into Samba.

I don't understand why JA thinks this is a hack.  Their current
method doesn't work, or at least isn't portable.  I've tried this
on Solaris 10, and it works just as it does in FreeBSD.  Test
program included after signature.

  $ ./test_sigprocmask
  Sending signal 16
  Got signal 16, blocked: true
  Blocking signal 16 using method 0
  Handled signal 16, blocked: false

  Sending signal 16
  Got signal 16, blocked: true
  Blocking signal 16 using method 1
  Handled signal 16, blocked: true

--
DE


#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <ucontext.h>
#include <unistd.h>


#define SIGNAL_TO_USE   SIGUSR1

static int      got_signal = 0;
static int      method = 0;

static char *
signal_blocked_str(sigset_t *set)
{
        if (sigismember(set, SIGNAL_TO_USE))
                return ("true");
        else
                return ("false");
}

static void
sighandler(int sig, int code, ucontext_t *ucp)
{
        sigset_t set;

        sigprocmask(SIG_SETMASK, NULL, &set);
        printf("Got signal %d, blocked: %s\n", SIGNAL_TO_USE,
            signal_blocked_str(&set));

        printf("Blocking signal %d using method %d\n", SIGNAL_TO_USE, method);
        if (method == 0) {
                sigaddset(&set, SIGNAL_TO_USE);
                sigprocmask(SIG_SETMASK, &set, NULL);
        } else
                sigaddset(&ucp->uc_sigmask, SIGNAL_TO_USE);
        got_signal = 1;
}

int
main(int argc, char **argv)
{
        sigset_t mask;
        struct sigaction act;

        /* Install the handler. */
        sigemptyset(&act.sa_mask);
        sigaddset(&act.sa_mask, SIGNAL_TO_USE);
        act.sa_handler = sighandler;
        act.sa_flags = SA_SIGINFO;
        assert(sigaction(SIGNAL_TO_USE, &act, NULL) == 0);

        /* Unblock the signal. */
        sigemptyset(&mask);
        sigaddset(&mask, SIGNAL_TO_USE);
        sigprocmask(SIG_UNBLOCK, &mask, NULL);

        printf("Sending signal %d\n", SIGNAL_TO_USE);
        kill(getpid(), SIGNAL_TO_USE);
        while (got_signal == 0) {
                sleep(1);
        }
        sigprocmask(SIG_SETMASK, NULL, &mask);
        printf("Handled signal %d, blocked: %s\n\n", SIGNAL_TO_USE,
            signal_blocked_str(&mask));

        method = 1;
        printf("Sending signal %d\n", SIGNAL_TO_USE);
        kill(getpid(), SIGNAL_TO_USE);
        while (got_signal == 0) {
                sleep(1);
        }
        sigprocmask(SIG_SETMASK, NULL, &mask);
        printf("Handled signal %d, blocked: %s\n", SIGNAL_TO_USE,
            signal_blocked_str(&mask));

        return (0);
}

_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[email protected]"

Reply via email to