在exec之后,信号SIGCHLD不是SIG_IGN,即使它之前是SIG_IGN

时间:2014-06-10 04:01:47

标签: python c++

这是我的计划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 :(得分: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提供豁免的原因。

出于好奇,您使用的是哪个平台?