我正在编写一个小型应用程序,我希望使其尽可能可移植(Linux、*BSD 和可能的其他 UNIX)。我的主要问题是管理EINTR
。我读到,某些系统上有一些系统调用可以返回,EINTR
尽管没有记录(例如stat(2)
在 Linux 上)。它是否正确?
我当前的解决方案是对每个系统调用使用包装器来重试EINTR
,即使记录为不返回此错误。这在所有“POSIX 兼容”系统上安全吗?使用这种方法可能会出现什么问题?真的推荐/需要吗?
答案1
我读到,某些系统上的某些系统调用可以返回 EINTR,尽管没有记录(例如 Linux 上的 stat(2))。它是否正确?
除非您已阻止所有信号,否则每个可以阻止 I/O 的系统调用都可以返回EINTR
.这是内核的通用行为,因此没有为每个此类系统调用重复记录它是合理的。您也不希望找到重复的文档EIO
出于同样的原因,在每个 I/O 系统调用上。
更广泛地说,Linux 手册页没有详尽地列出它们可以返回的错误。不仅有上面这样的情况,内核中还有很多分层,那么每个 syscal 的作用是什么?能回报取决于涉及哪些司机等。如果返回 -1 时引用 XFS 文件系统上的文件,则返回 -1errno
时可能值的集合将与引用 FIFO 时read(2)
不同。fd
期望手册页给出所有可能的错误返回代码的并集是不合理的;它会很大程度上概括errno(3)
如果是的话。
使用这种方法可能会出现什么问题?真的推荐/需要吗?
在您的应用程序中,盲目地重新启动系统调用可能不是正确的做法。系统调用返回EINTR
使您的应用程序有机会在调用上下文中处理信号,而不是在信号处理程序的上下文中处理信号。例如,这可以帮助您避免全局变量。
有关此问题的一种观点,请参阅EINTR
它有什么好处。
另请注意sigaction
该文章中提出的观点:您可以使用以下命令控制此行为SA_RESTART
。如果您的下一个问题是是否应该将该标志设置为 1 还是 0,那么答案是这取决于您的应用程序。