posix关闭呼叫失败怎么办?

时间:2015-10-13 23:18:22

标签: c linux unix error-handling posix

在我的系统(Ubuntu Linux,glibc)上,close调用的手册页指定了它可以返回的几个错误返回值。它还说

  

不检查close()的返回值是一个常见但严重的编程错误。

并且同时

  

请注意,返回值仅应用于诊断。特别是在EINTR之后不应该重试close(),因为这可能导致另一个线程的重用描述符被关闭。

因此我不允许忽略返回值,也不允许重试该呼叫。

鉴于此,我该如何处理close()呼叫失败?

如果在我向文件写入内容时发生错误,我可能应该尝试在其他地方写入信息以避免数据丢失。

如果我只是在阅读文件,我可以记录失败并继续假装没有发生的程序吗?是否有任何警告,文件描述符泄漏或其他什么?

2 个答案:

答案 0 :(得分:6)

实际上,永远不应该在出错时重试close,并且在close返回后传递给close的fd始终无效(关闭),无论是否发生错误。在某些情况下,错误可能表示数据丢失(某些NFS设置)或设备的异常硬件条件(例如磁带无法倒带),因此您可能需要小心避免数据丢失,但您绝不应尝试再次关闭fd。

理论上,POSIX过去不清楚当closeEINTR失败而fd是否仍未打开,系统不同意。由于了解状态非常重要(否则你有fd泄漏或双重错误在多线程程序中非常危险),Austin Group issue #529的解析严格指定了POSIX的未来版本的行为, EINTR表示fd仍然开放。这是与其他地方的EINTR定义一致的正确行为,但Linux拒绝接受它。 (对于这个,可以在libc系统调用包装器级别进行简单的解决方法;请参阅glibc PR #14627。)幸运的是,它实际上从未出现过。

您可能会发现一些相关问题:

答案 1 :(得分:1)

首先:EINTR意味着:系统调用被中断,如果在close()调用中发生这种情况,那么您无能为力。

除了可能跟踪事实之外,如果fd属于某个文件,这个文件可能已损坏,根据返回值,您对close()上的错误几乎无法做多少。 AFAIK唯一一个可以重试关闭的案例是EBUSY,但我还没有看到。

所以:

  • 不检查close()的结果可能意味着您错过了文件损坏,尤其是截断。
  • 根据错误,大部分时间你都无能为力 - 失败的close()只是意味着在你的申请范围之外出现了一些错误。