OS X sigaction未正确设置sa_掩码

OS X sigaction未正确设置sa_掩码,c,macos,language-lawyer,sigprocmask,sigaction,C,Macos,Language Lawyer,Sigprocmask,Sigaction,在macbook(OSX 10.9.5(13F34))上,执行以下简单程序: #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 s

在macbook(OSX 10.9.5(13F34))上,执行以下简单程序:

#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;
}
我希望
osa
sa_mask
成员与
sigprocmask
给出的
mask
匹配

POSIX是否对此字段指定了任何要求?手册页中唯一提到的是不可阻止的信号,如
SIGKILL
,其中该值未指定

在linux上,此程序打印:

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
正如所料

gcc版本为:

$ 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
二进制文件链接到:

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
我希望
osa
sa_mask
成员与
sigprocmask
给出的
mask
匹配

你的期望是错误的

这里有到的链接。书签

在执行信号捕获功能期间要阻止的附加信号集

没有理由期望
osa.sa_mask
匹配
mask
。您的
掩码
是当前的信号掩码。您的
osa.sa_掩码
是一个附加的信号掩码,在调用
osa.sa_处理程序
处理一个
SIGALRM
时会应用它

在您的测试用例中,
osa.sa_handler
SIG_DFL
,因此
osa.sa_mask
的内容是无关的。据我所知(经过简短的搜索),POSIX没有说明osa.sa_mask应该是什么,就像在您的测试用例中一样,自最近的
exec
以来,进程没有为信号设置操作

此外,当系统调用已安装的
SIGALRM
处理程序时,它会自动在信号掩码中包含
SIGALRM
(除非您在安装处理程序时通过了
SA_NODEFER
SA_RESETHAND
)。引用上面链接的文档:

当信号被
sigaction()
安装的信号捕获函数捕获时,在信号捕获函数期间(或在调用
sigprocmask()
sigssuspend()
之前),计算并安装一个新的信号掩码。该掩码是通过获取当前信号掩码和正在传送的信号的
sa_掩码
的值的并集而形成的,除非设置了
sa_NODEFER
sa_RESETHAND
,否则包括正在传送的信号

因此,如果
sa_标志
为0,则
sa_掩码
是否包含
SIGALRM
是无关的。事实上,Linux不包括它,OSX也不包括它,这对信号的处理没有影响


还请注意,(对我来说)不清楚为
sigprocmask
how
参数传递0(而不是一个定义的常量)是否合法,即使
set
参数为空。但我发现将其更改为
SIG_BLOCK
没有任何区别。

您在OS X上使用的库(和版本)是什么?
errno
在每次
sig*
呼叫后都会说些什么吗?@BlueMoon更新了问题以回答您的问题我相信这是正确的答案。如果我们有10.9.5的
libSystemB.dylib
或更好的源代码的副本,我们可能会发现,出于礼貌,它在sigset中设置了该位。回答得好!
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)