在 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;
}

神秘地打印:
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

我希望 sa_maskosa 成员与 mask 给出的 sigprocmask 匹配。

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)

最佳答案



你的期望是错误的。

这是 the current (as of this writing) official POSIX documentation 的链接。收藏它!

Here is what that documentation says about sa_mask :



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

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

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



因此,如果 sa_mask 为 0,则 SIGALRM 是否包含 sa_flags 无关紧要。Linux 不包含它而 OS X 包含它这一事实对信号的处理没有影响。

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

关于c - OS X sigaction 错误地设置了 sa_mask,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27159255/

10-11 04:17