检查 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
,它用于跟踪信息和重新启动系统调用的参数
我发现这段代码被使用了好几次(也有类似的代码使用 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 ifSA_RESTART
is specified insigaction(2)
负责此任务的是 restart_block
,它用于跟踪信息和重新启动系统调用的参数