在 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_mask
的 osa
成员与 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_handler
是 SIG_DFL
,因此 osa.sa_mask
的内容无关紧要。据我所知(经过简短搜索后),POSIX 没有说明 osa.sa_mask
应该是什么,就像在您的测试用例中一样,自最近的 exec
以来,该进程尚未为信号设置操作。
此外,当系统调用已安装的 SIGALRM
处理程序时,它会自动在信号掩码中包含 SIGALRM
(除非您在安装处理程序时传递了 SA_NODEFER
或 SA_RESETHAND
)。引用上面链接的文档:
因此,如果 sa_mask
为 0,则 SIGALRM
是否包含 sa_flags
无关紧要。Linux 不包含它而 OS X 包含它这一事实对信号的处理没有影响。
另请注意,(对我而言)不清楚为 how
的 sigprocmask
参数传递 0(而不是定义的常量之一)是否合法,即使 set
参数为空。但我发现将其更改为 SIG_BLOCK
没有任何区别。
关于c - OS X sigaction 错误地设置了 sa_mask,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27159255/