Linux C,waitpid()被处理信号解除阻塞,返回值为-1,错误为5

时间:2017-08-14 07:13:26

标签: c linux signals kill waitpid

几个小时前我遇到了这个问题。

即使我已修复它,但我根本不明白为什么会这样。

signal(SIGHUP, sighupHandler);
.
.
.
// sync with child by getting a char written by child
fgetc(pipe_in);
close(pipe_in);
int status;
if(waitpid(initProcessPid, &status, 0) == -1){
    printf("debug: errno is %d\n", errno);
    printf("failed to wait for init process to end\n");
}

每次在waitpid()块期间发生SIGHUP时,waitpid()都返回-1,错误为5。

虽然EINTR在这种情况下应该是由er指出的,但是EINTR是4而不是5。

几个小时后从gdb收集想法,因为我目前没有在SIGHUP上做任何事情,所以我将代码更改为:

signal(SIGHUP, SIG_IGN);

然后它正常工作,SIGHUP不再破坏waitpid()块。

我正在研究一个旨在成为单个文件和静态的Linux容器。 https://github.com/Kethen/minicontainer

1 个答案:

答案 0 :(得分:0)

根据wait()/waitpid() POSIX documentaion

  

wait()函数将导致调用线程被阻塞,直到子进程终止生成的状态信息可供线程 使用,或者直到传递其动作为执行信号捕捉功能或终止过程, 或发生错误。

     

如果wait()waitpid()由于向调用进程发送信号而返回,则返回-1并将errno设置为[EINTR]

由于您已将SIGHUP配置为执行某项功能,因此上述强调条款涵盖了该功能。

这与许多其他系统调用类似,当被信号中断时,它们可以返回EAGAIN。您可以使用的一种方法是使用类似于以下的代码:

// Keep waiting while being interrupted.

int rc, err;
do {
    rc = waitpid (initProcessPid, &status, 0);
    err = errno;
} while ((rc == -1) && (err == EINTR));

// Any error other than interruption will be caught here.

if (rc == -1) {
    printf ("debug: errno is %d\n", err);
    printf ("failed to wait for init process to end\n");
}

您也正确认为Linux通常会说明4而不是5,但情况并非总是如此。有些系统使用截然不同的值(例如IBM iSeries,将这些常见错误代码放在大约3400处)。

您应该检查特定的名称而不是固定值。