【发布时间】:2019-11-22 15:00:59
【问题描述】:
在exec() 期间,阻塞信号的掩码(由sigprocmask() 设置)由子进程继承。
但现在我注意到在Linux下,也有忽略信号的掩码(grep < /proc/self/status ^SigIgn),它也被子进程继承。由于这些是由sigaction() 和act.sa_handler = SIG_IGN 设置的,所以我预计,作为信号处理程序,它们在执行期间会被重置。但他们不是。
考虑下面的例子:父母想忽略 SIGINT,但这也延伸到孩子,因此sleep 120 不能再被kill -INT $(pidof sleep) 杀死。
问题:
这是否符合 POSIX? sigaction() 的文档明确指出
sigaction的影响不会存在exec(引用:“...直到调用其中一个 exec 函数”)。 Linux 手册页说“忽略信号的配置保持不变”我猜这是 Linux 特有的功能。如何正确可靠地重置忽略掩码?我没有发现
sigprocmask()的模拟 - 管理阻塞信号 - 管理忽略信号的掩码。我是否应该简单地遍历所有信号并使用sigaction()重置它们?
附:使用内核 v3.x 和 v4.9 进行测试,行为相同。
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
struct sigaction act;
sigset_t ss;
system("grep -n < /proc/self/status ^SigIgn");
memset(&act, 0, sizeof(act));
act.sa_handler = SIG_IGN;
sigaction( SIGINT, &act, NULL );
system("grep -n < /proc/self/status ^SigIgn");
sigemptyset(&ss);
sigprocmask(SIG_SETMASK, &ss, NULL);
system("grep -n < /proc/self/status ^SigIgn");
system("sleep 120");
return 0;
}
【问题讨论】:
-
你不能用
sigprocmask和sigemptyset来重置你分叉的阻塞信号吗?这可能会对您有所帮助:Set and Oldset in sigprocmask()