在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
的{{1}}成员与osa
的{{1}}匹配mask
。
POSIX是否指定了此字段的任何要求?在联机帮助页中唯一提到的是关于像sigprocmask
这样的不可阻塞的信号,其中该值未指定。
在linux上,该程序打印:
SIGKILL
正如所料。
gcc版本是:
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 --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
答案 0 :(得分:7)
我希望
sa_mask
的{{1}}成员与osa
给出的mask
匹配。
您的期望不正确。
这是the current (as of this writing) official POSIX documentation的链接。收藏它!
Here is what that documentation says about sa_mask
:
执行信号捕捉功能时要阻止的附加信号集。
没有理由期望sigprocmask
与osa.sa_mask
匹配。您的mask
是当前信号掩码。您的mask
是一个附加信号掩码,在调用osa.sa_mask
以处理osa.sa_handler
时已应用。
在您的测试用例中,SIGALRM
为osa.sa_handler
,因此SIG_DFL
的内容无关紧要。据我所知(在简短的搜索之后),POSIX没有说明osa.sa_mask
应该是什么时候,就像你的测试案例一样,这个过程自最近以来没有为信号设置一个动作{ {1}}。
此外,当系统调用已安装的osa.sa_mask
处理程序时,它会自动在信号掩码中包含exec
(除非您在安装处理程序时通过SIGALRM
或SIGALRM
)。引用上面链接的文档:
当信号被
SA_NODEFER
安装的信号捕获功能捕获时,会在信号捕获功能的持续时间内计算并安装新的信号掩码(或直到调用SA_RESETHAND
或sigaction()
。该掩模是通过将当前信号掩码与正在传递的信号的sigprocmask()
的值结合而形成的,除非设置sigsuspend()
或sa_mask
,否则包括信号递送
因此,如果SA_NODEFER
为0,SA_RESETHAND
是否包含sa_mask
则无关紧要.Linux不包含它和OS X的事实对我来说无关紧要处理信号。
另请注意,对于SIGALRM
的{{1}}参数,传递0(而不是一个已定义的常量)是合法的(对我来说)是不合法的,即使sa_flags
参数为null。但我发现将其更改为how
没有任何区别。