c - Linux C,waitpid() 被具有返回值 -1 和 errno 5 的已处理信号解除阻塞

标签 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() 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() or waitpid() returns due to the delivery of a signal to the calling process, -1 shall be returned and errno 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/

相关文章:

c++ - 内存不足opencv haartraining

linux - Apache ScriptAlias 无法设置脚本参数

c++ - 强制应用程序核心转储并退出的正确方法是什么?

python - 如何在 Pyrex 中定义初始化的 C 数组?

c - 如何使用c锁定然后解锁sqlite数据库?

无法使用 OpenAL 捕获 send() 失败

linux - Unix 上的应用程序控制脚本

python - python线程中超时信号的替代方法

c - 在 C 中使用信号、处理程序、kill 和 getpid

c - 未知类型名称 C