我正在编写一个小应用程序,我想使它尽可能地可移植(Linux,*BSD,可能还有其他UNIXes)。我的主要问题是EINTR的管理。我读到,有些系统调用可以返回EINTR,尽管它没有文档化(例如stat(2)在Linux上)。这是正确的吗?
我目前的解决方案是对每个系统调用使用包装器在EINTR上重试,即使它被记录为不返回此错误。这在所有"POSIX兼容“系统上都是安全的吗?使用这种方法有什么不对呢?它真的是推荐的/需要的吗?
发布于 2018-09-10 18:37:27
我读到有些系统调用可以返回EINTR,尽管它没有文档化(例如,Linux上的stat(2) )。这是正确的吗?
除非阻塞了所有信号,否则可以阻止I/O上的每个系统调用返回EINTR。这是内核的一个通用行为,因此没有为每个这样的syscall重复记录是有道理的。出于同样的原因,您也不会期望在每个I/O syscall上找到EIO的重复文档。
更广泛地说,Linux手册页没有列出它们可以返回的错误。您不仅有上述情况,内核中也有很多分层,所以每个系统能够返回什么取决于所涉及的驱动程序等。当errno返回-1时,如果fd引用XFS文件系统上的文件,则可能的D6值集将与引用FIFO时不同。期望手册页会将所有可能的错误返回代码合并在一起是不合理的;如果这样做,它将在很大程度上重复errno(3)。
使用这种方法有什么不对呢?它真的是推荐的/需要的吗?
在您的应用程序中盲目地重新启动syscalls可能不是正确的事情。Syscalls返回EINTR给应用程序在调用上下文中处理信号的机会,而不是在信号处理程序的上下文中。例如,这可以帮助您避免全局变量。
有关此问题的一个透视图,请参见EINTR以及它有什么好处。
还请注意本文中提到的sigaction点:您可以使用SA_RESTART来控制这种行为。如果您的下一个问题是应该将标志设置为1还是0,那么答案是它取决于您的应用程序。
https://unix.stackexchange.com/questions/468064
复制相似问题