I have this code where I use sigaddset and sigaction. However if I comment segaddset the result is the same
struct sigaction act;
act.sa_handler = process_alarm;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
//sigaddset(&act.sa_mask, SIGINT);
sigaction(SIGALRM, &act, NULL);
for(;;)
{
alarm(3);
pause();
}
Why do I need to use it?
You are doing 2 things here:
Populating a sigset_t
. A sigset_t is just a collection of values for signals, and are used in various system calls. You can:
Setting the signal mask for the signal handler. You do that by manipulating the sigset_t sa_mask
member of the struct sigaction
when you set up a signal handler in with a call to sigaction().
The signal mask of a signal handler means that while the signal handler is executing, the signals that are in the mask will be blocked - i.e. those signals will not be handled as long as they are blocked. When the signal handler are finished, the signals in will be unblocked. A signal that is blocked isn't "lost", it will be handled when that particular signal is unblocked again.
The sigaddset(&act.sa_mask, SIGINT);
means the the SIGINT signal cannot occur while the code for the SIGALRM
handler is running.
On the other hand, if you comment out sigaddset(&act.sa_mask, SIGINT);
, you're left with just an empty list of signals created with sigemptyset(&act.sa_mask);
. So any signals that occur while the SIGALRM handler function is running might preempt that handler and execute the signal handler for that other signal.
For a SIGINT, you would normally not notice any difference with manual testing - it's unlikely you manage to hit CTRL-C exactly when your handler for SIGALRM is running, and your SIGALRM handler probably runs quickly enough that you would not notice if the SIGINT was slightly delayed.