Pending signals not being delivered

297 views Asked by At

I wrote this program to check blocking of SIGQUIT signal. The problem is after restoring to the previous state, the signal is pending but it isn't being delivered.

Here's the main program

sigset_t newmask, oldmask, pendmask;
if(signal(SIGQUIT,sig_quit)==SIG_ERR)   //Register signal handler
    printf("\nerror\n");
sigemptyset(&newmask);
sigaddset(&newmask,SIGQUIT);
sigprocmask(SIG_BLOCK,&newmask,&oldmask);   //Save previous value and block SIGQUIT 
sleep(5);
sigpending(&pendmask);
if(sigismember(&pendmask,SIGQUIT)){ //Check if SIGQUIT is pending
    printf("\nSIGQUIT pending..\n");
    fflush(stdout);
}
sigprocmask(SIG_BLOCK,&oldmask,NULL);   //Restore old value of sigset
printf("\nSIGQUIT unblocked\n");
fflush(stdout);
sleep(5);   //Sleep again to check if everything is A-okay!

I can understand that in the first sleep the signal is blocked. But even after unblocking, in the second sleep function, the program isn't responding to SIGQUIT.

What could be the possible problem here?

P.S I'm using CentOs

Here's the handler function

void sig_quit(int i)
{
     printf("\nSIGQUIT caught\n");
     fflush(stdout);
     signal(SIGQUIT,SIG_DFL);
}
1

There are 1 answers

1
whoan On BEST ANSWER

That's because you aren't unblocking SIGQUIT when you think you are:

sigprocmask(SIG_BLOCK,&oldmask,NULL);   //Restore old value of sigset

With SIG_BLOCK, sigprocmask is adding oldmask to the currently blocked signals.

Try instead:

sigprocmask(SIG_SETMASK,&oldmask,NULL);   //Restore old value of sigset

Furthermore, in sig_quit you are using printf which is not an async-signal-safe function. You can use, for example, write instead.