执行后,信号SIGCHLD不再是SIG_IGN,即使它之前是SIG_IGN
After an exec, signal SIGCHLD is not SIG_IGN even though it was SIG_IGN before
这是我的程序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 errorn", command);
return -1;
}
char result[256]={0};
int len = fread(result, sizeof(char), 256, file);
printf("result is :%sn", result);
int ret = pclose(file);
if (ret == -1)
{
printf("pclose error:%d, errno:%d, str_err:%sn", 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_sign ?
您没有尊重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
提供豁免的原因。
出于好奇,请问您使用的是哪个平台?