download original
  
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
void check_sigmask(const char *msg) {
    sigset_t ss;
    sigprocmask(0, 0, &ss);
    printf("%s: SIGINT blocked: %i\n", msg, sigismember(&ss, SIGINT));
}
sigjmp_buf jbuf;
volatile sig_atomic_t canjump = 0;
void sig_handler(int signum) {
    if (!canjump) {
        printf("too early signal\n");
        return;
    }
    check_sigmask("in sig handler");
    siglongjmp(jbuf, 1);
}
int main() {
    signal(SIGINT, sig_handler);
    for (volatile int i=0; i<499999999; i++) { }  // busy loop to make it easier to trigger "too early signal" race
    check_sigmask("after handler initialization");
    if (1 == sigsetjmp(jbuf, 1)) {
        check_sigmask("after handler return");
    } else {
        canjump = 1;
        printf("waiting for SIGINT...\n");
        pause();
    }
}
/*
(OSX & Linux)
$ ./unblocktest
after handler initialization: SIGINT blocked: 0
waiting for SIGINT...
^Cin sig handler: SIGINT blocked: 1
after handler return: SIGINT blocked: 0
$
*/
//19:55 < multi_io_> question: the automatic signal unblocking upon return from the signal handler -- how does that work if the handler isn't ended via sigreturn?
//19:55 < multi_io_> I just tested it, returned from the handler via longjmp. The signal still gets unblocked.
//=>
// man siglongjmp:
 //      The sigsetjmp()/siglongjmp() function pairs save and restore the signal mask if the argument savemask is non-zero; otherwise, only the register set and the stack are saved.
  
   back to signals 
  
  (C) 1998-2017 Olaf Klischat  <olaf.klischat@gmail.com>