在我的系统(Ubuntu Linux,glibc)上,close
调用的手册页指定了它可以返回的几个错误返回值。它还说
不检查close()的返回值是一个常见但严重的编程错误。
并且同时
请注意,返回值仅应用于诊断。特别是在EINTR之后不应该重试close(),因为这可能导致另一个线程的重用描述符被关闭。
因此我不允许忽略返回值,也不允许重试该呼叫。
鉴于此,我该如何处理close()
呼叫失败?
如果在我向文件写入内容时发生错误,我可能应该尝试在其他地方写入信息以避免数据丢失。
如果我只是在阅读文件,我可以记录失败并继续假装没有发生的程序吗?是否有任何警告,文件描述符泄漏或其他什么?
答案 0 :(得分:6)
实际上,永远不应该在出错时重试close
,并且在close
返回后传递给close
的fd始终无效(关闭),无论是否发生错误。在某些情况下,错误可能表示数据丢失(某些NFS设置)或设备的异常硬件条件(例如磁带无法倒带),因此您可能需要小心避免数据丢失,但您绝不应尝试再次关闭fd。
理论上,POSIX过去不清楚当close
因EINTR
失败而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()
只是意味着在你的申请范围之外出现了一些错误。