这是我的计划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?
答案 0 :(得分:0)
您不尊重sigprocmask()
参数的限制限定符。你的编译器应该抱怨两次使用相同的参数。
execv()
文档的POSIX规范:
设置为调用过程映像中的默认操作(SIG_DFL)的信号应设置为新过程映像中的默认操作。除SIGCHLD外,调用过程映像设置为忽略的信号(SIG_IGN)应设置为被新过程映像忽略。
如果调用过程映像将SIGCHLD信号设置为忽略,则不指定SIGCHLD信号是被设置为忽略还是新过程映像中的默认操作。
OP评论:
但是“UNIX环境中的高级编程”表示如果SIGXXX信号设置为被调用过程映像忽略,在新过程中信号也会被忽略?
不同之处在于APUE正在处理UNIX; UNIX实际上并不是POSIX(尽管两者都很接近)。 POSIX表示平台可以符合POSIX标准,并且即使在原始流程中为SIGCHLD
,仍会将SIG_DFL
重置为SIG_IGN
。您的代码似乎表明您的平台是POSIX为SIGCHLD
提供豁免的原因。
出于好奇,您使用的是哪个平台?