On a macbook (OSX 10.9.5 (13F34)) the following simple program:
#include <stdio.h>
#include <signal.h>
static void nop(int unused) { }
int
main(void) {
struct sigaction sa, osa;
sigset_t mask;
sigemptyset(&sa.sa_mask);
printf("Errno after sigempty sa_mask: %d\n", errno);
sigemptyset(&osa.sa_mask);
printf("Errno after sigempty oldsa_mask: %d\n", errno);
sa.sa_flags = 0;
sa.sa_handler = nop;
sigprocmask(0, NULL, &mask);
printf("Errno after sigprocmask mask: %d\n", errno);
printf("%d\n", sigismember(&mask, SIGALRM));
sigaction(SIGALRM, &sa, &osa);
printf("Errno after sigaction sa osa: %d\n", errno);
printf("%d\n", sigismember(&osa.sa_mask, SIGALRM));
printf("%d\n", sigismember(&sa.sa_mask, SIGALRM));
return 0;
}
Mysteriously prints:
Errno after sigempty sa_mask: 0
Errno after sigempty oldsa_mask: 0
Errno after sigprocmask mask: 0
0
Errno after sigaction sa osa: 0
1
0
I would expect that the sa_mask member of osa to match mask as given by sigprocmask.
Does POSIX specify any requirements for this field? The only mention of it in the manpages is with regard to unblockable signals like SIGKILL, where that value is unspecified.
On linux, this program prints:
Errno after sigempty sa_mask: 0
Errno after sigempty oldsa_mask: 0
Errno after sigprocmask mask: 0
0
Errno after sigaction sa osa: 0
0
0
as expected.
The gcc version is:
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darw
The binary is linked against:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
Your expectation is incorrect.
Here's a link to the current (as of this writing) official POSIX documentation. Bookmark it!
Here is what that documentation says about
sa_mask:There is no reason to expect
osa.sa_maskto matchmask. Yourmaskis the current signal mask. Yourosa.sa_maskis an additional signal mask that would have been applied during a call toosa.sa_handlerto handle aSIGALRM.In your test case,
osa.sa_handlerisSIG_DFL, so the contents ofosa.sa_maskis irrelevant. As far as I know (after a brief search), POSIX says nothing about whatosa.sa_maskshould be when, as in your test case, the process hasn't set an action for the signal since the most recentexec.Furthermore, when the system calls an installed
SIGALRMhandler, it includesSIGALRMin the signal mask automatically (unless you passedSA_NODEFERorSA_RESETHANDwhen you installed the handler). Quoting the documentation linked above:Thus it's irrelevant whether
sa_maskincludesSIGALRMifsa_flagsis 0. The fact that Linux doesn't include it and OS X does makes no difference to the handling of the signal.Note too that it's not clear (to me) that it's legal to pass 0 (instead of one of the defined constants) for the
howargument ofsigprocmask, even when thesetargument is null. But I found that changing it toSIG_BLOCKmade no difference.