检查 errno != EINTR:这是什么意思?

Checking if errno != EINTR: what does it mean?

我发现这段代码被使用了好几次(也有类似的代码使用 open() 而不是 write())。

int c = write(fd, &v, sizeof(v));
if (c == -1 && errno != EINTR) {
    perror("Write to output file");
    exit(EXIT_FAILURE);
}

这里为什么要勾选&& errno != EINTR

man 上寻找 errno 我发现了以下关于 EINTR 的文字,但即使我访问了 man 7 signal 也没有赐教。

EINTR Interrupted function call (POSIX.1); see signal(7).

来自 write 上的 man page

The call was interrupted by a signal before any data was written

如果在系统调用过程中出现信号,许多系统调用将报告 EINTR 错误代码。实际上并没有发生错误,只是这样报告的,因为系统无法自动恢复系统调用。这种编码模式只是在发生这种情况时重试系统调用,以忽略中断。

例如,如果程序在计时器 运行 结束时异步使用 alarm() 到 运行 某些代码,则可能会发生这种情况。如果在程序调用 write() 时发生超时,我们只想重试系统调用(又名 read/write 等)。

这里的答案非常好,我想添加一些内部细节:

System calls that are interrupted by signals can either abort and return EINTR or automatically restart themselves if and only if SA_RESTART is specified in sigaction(2)

负责此任务的是 restart_block,它用于跟踪信息和重新启动系统调用的参数