exec后信号SIGCHLD未被设置为SIG_IGN,尽管之前是SIG_IGN
这是我的程序 popen_test.cpp
:
int main(int argc, char* argv[])
{
signal(SIGCHLD, SIG_IGN);
sigset_t sset;
sigaddset(&sset, SIGCHLD);
sigprocmask(SIG_UNBLOCK, &sset, &sset);
char command[128] = {0};
snprintf(command, sizeof(command), "python popen_test.py");
FILE* file;
file = popen(command, "r");
if ( !file )
{
printf("command: %s is error\n", command);
return -1;
}
char result[256]={0};
int len = fread(result, sizeof(char), 256, file);
printf("result is :%s\n", result);
int ret = pclose(file);
if (ret == -1)
{
printf("pclose error:%d, errno:%d, str_err:%s\n", ret, errno, strerror(errno));
return -1;
}
}
脚本是
import os
import signal
import subprocess
if __name__ == "__main__":
test = signal.getsignal(signal.SIGCHLD)
if test == signal.SIG_DFL:
print "sig_dfl"
if test == signal.SIG_IGN:
print "sig_ign"
print test
POPEN 会创建一个子进程;这个子进程会调用 exec
来运行 python popen_test.py
。我知道当调用 exec
时,SIGCHLD 信号(如果设置为 SIG_IGN)可能会被重置为 SIG_DFL,但为什么结果是 sig_dfl,而不是 sig_ign 呢?
1 个回答
0
你没有遵循对 sigprocmask()
函数参数的限制。你的编译器应该会对你重复使用同一个参数发出警告。
关于 execv()
函数,POSIX 规范中有这样的说明:
在调用进程中设置为默认动作(SIG_DFL)的信号,在新进程中也应该设置为默认动作。除了 SIGCHLD 之外,调用进程中设置为忽略(SIG_IGN)的信号,在新进程中也应该设置为忽略。
如果调用进程中将 SIGCHLD 信号设置为忽略,那么在新进程中该信号是被忽略还是恢复为默认动作就不确定了。
这位 提问者 评论道:
但是《UNIX环境高级编程》说如果调用进程中将 SIGXXX 信号设置为忽略,那么在新进程中该信号也应该被忽略?
这里的区别在于,APUE 讨论的是 UNIX,而 UNIX 并不完全等同于 POSIX(虽然两者很接近)。POSIX 规定一个平台可以符合 POSIX 标准,但仍然可以将 SIGCHLD
重置为 SIG_DFL
,即使在原始进程中它是 SIG_IGN
。你的代码似乎表明你的平台就是 POSIX 为什么对 SIGCHLD
有这个例外的原因。
顺便问一下,你使用的是哪个平台?