I was reading my textbook's chapter (CS:APP, 3rd ed., chapter 8, page 781) on signals/ECF for Linux x86-64 systems, and came across this:
The sigsuspend function temporarily replaces the current blocked set with mask and then suspends the process until the receipt of a signal whose action is either to run a handler or to terminate the process. If the action is to terminate, then the process terminates without returning from sigsuspend. If the action is to run a handler, then sigsuspend returns after the handler returns, restoring the blocked set to its state when sigsuspend was called.
The sigsuspend function is equivalent to an atomic (uninterruptible) version of the following:
1 sigprocmask(SIG_BLOCK, &mask, &prev); 2 pause(); 3 sigprocmask(SIG_SETMASK, &prev, NULL);
As I understand it, sigprocmask(SIG_BLOCK, &mask, &prev)
should result in the blocked set being OR-ed with mask, i.e. adding the signals in mask to those already in the blocked set. But the text directly above the code (and the man-page for sigsuspend, which I looked up) says that sigsuspend "temporarily replaces the current blocked set with mask". That sounds more like sigprocmask(SIG_SETMASK, &mask, &prev)
to me, where the blocked set is just set equal to the signals in the mask.
So why is sigsuspend(&mask)
equivalent to the code above (lines 1-3) and not the code below (lines 4-6)? Where did I go wrong in my intuition and/or understanding of signal.h functions?
4 sigprocmask(SIG_SETMASK, &mask, &prev);
5 pause();
6 sigprocmask(SIG_SETMASK, &prev, NULL);
If I'm not being clear, let me ask a concrete question instead (it might explain my intuition better). Say the current blocked set encodes SIGCHLD, and the sigset_t mask encodes SIGINT. I call sigsuspend(&mask)
. No matter which code interpretation is right (lines 1-3 OR 4-6), a SIGINT signal delivered just after the call to sigsuspend would be blocked/not wake up the process. However, what if right after the call to sigsuspend, a SIGCHLD signal is delivered? Will the process wake up/receive the signal? My intuition says lines 1-3 would block a SIGCHLD while lines 4-6 wouldn't, so clearly lines 1-3 and 4-6 aren't equivalent. But my intuition also says that sigsuspend shouldn't block SIGCHLD because it's not in mask, so lines 4-6 are correct, and if lines 4-6 are equivalent to sigsuspend in this case, sigsuspend can't be equivalent to lines 1-3. Where did my intuition/understanding go wrong?