5

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?

alk
  • 69,737
  • 10
  • 105
  • 255
k0zm0tis
  • 69
  • 2
  • 1
    Well, I feel kind of stupid now. I'm not used to textbooks being wrong, I never would have thought to look for corrections made to the book. I'll check that in the future. Thanks! – k0zm0tis Apr 18 '19 at 18:41
  • Helpful hint: If your professor is the author of this textbook, broach this subject *very delicately*, or not at all. – Mark Benningfield Apr 18 '19 at 23:16
  • You might want to accept Mark's answer below? – alk Apr 27 '19 at 08:06

1 Answers1

4

The thing about technical books (and textbooks in particular) is that you should always be aware of whether or not there is errata available.

This link for the errata for that book shows:

Chapter 8: Exceptional Control Flow
...
...
p. 781. In the description of sigsuspend in the second paragraph, line 1 should be:
sigprocmask(SIG_SETMASK, &mask, &prev);
Posted 10/28/2015. Dave O'Hallaron

Mark Benningfield
  • 2,800
  • 9
  • 31
  • 31