Search code examples
clinuxsignalsposixalarm

What is sigaddset used for?


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?


Solution

  • You are doing 2 things here:

    1. Populating a sigset_t. A sigset_t is just a collection of values for signals, and are used in various system calls. You can:

      • Create an empty sigset_t (sigemptyset()
      • Add a signal to the set (sigaddset())
      • Remove a signal to the set (sigdelset())
      • etc...
    2. 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.