几个小时前我遇到了这个问题。
即使我已经修复了它,我还是不明白为什么会这样。
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() block 期间发生 SIGHUP,waitpid() 返回 -1 和 errno 5。
尽管正如 alk 所指出的,在这种情况下 EINTR 应该在 errno 中,但 EINTR 是 4,而不是 5。
在从 gdb 收集了几个小时的想法后,由于我目前实际上没有在 SIGHUP 上做任何事情,我将我的代码更改为:
signal(SIGHUP, SIG_IGN);
然后它就正常工作了,SIGHUP 不再破坏 waitpid() block 。
我正在开发一个旨在成为单个文件和静态的 linux 容器。 https://github.com/Kethen/minicontainer
最佳答案
根据 wait()/waitpid()
POSIX documentaion :
The
wait()
function shall cause the calling thread to become blocked until status information generated by child process termination is made available to the thread, or until delivery of a signal whose action is either to execute a signal-catching function or to terminate the process, or an error occurs.If
wait()
orwaitpid()
returns due to the delivery of a signal to the calling process, -1 shall be returned anderrno
set to[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 的某个位置)。
您应该检查特定的名称,而不是固定值。
关于c - Linux C,waitpid() 被具有返回值 -1 和 errno 5 的已处理信号解除阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45669213/