处理C语言只读文件关闭错误

4

我正在使用open、read和close进行一些基本的文件读取(文件以O_RDONLY访问模式打开)。

当关闭文件时,我想不到一个好的方法来处理可能出现的文件关闭错误,以确保文件正确关闭。

有什么建议吗?

2个回答

6
从我的经验来看,即使close失败了,它也会成功。这有几个原因。
我怀疑close在某些操作系统上开始失败的一个主要原因是AFS。AFS是一个来自80年代的分布式文件系统,具有有趣的语义——所有写操作都在本地缓存中完成,并且当您关闭文件时,数据将写入服务器。AFS还使用了到期的令牌进行加密身份验证。因此,您可能会遇到这样一个有趣的情况:您对文件所做的所有写操作都是在您的令牌有效期内完成的,但实际上与文件服务器通信的close却使用过期的令牌完成,这意味着您写入本地缓存的所有数据都会丢失。这就是为什么close需要向用户传达出现问题的原因。大多数文件编辑器都可以正确处理此问题(例如Emacs拒绝将缓冲区标记为未修改),但我很少看到其他应用程序能够处理此问题。
话虽如此,close实际上无法失败。closeexitexec(文件描述符关闭)和崩溃(核心转储)期间是隐含的。这些都是不能失败的情况。您不能让exit或崩溃因为关闭文件描述符失败而失败。如果exit失败怎么办?崩溃呢?如果崩溃也失败了,我们在这之后该去哪里?另外,由于几乎没有人检查close的错误,如果失败是常见的,您将面临文件描述符泄漏和信息泄漏的风险(假设我们在生成非特权进程之前未能关闭某些文件描述符)。所有这些对于操作系统来说都太危险了,所以我看过的所有操作系统(*BSD、Linux、Solaris)即使底层文件系统关闭操作失败,也会关闭文件描述符。
实际上,这意味着您只需调用close并忽略其返回的任何错误即可。如果您有一种优雅的方法来处理它失败的情况,例如编辑器,则可以向用户发送消息并让用户解决问题并重新打开文件、写入数据并尝试再次关闭。不要在循环或其他方式中自动执行任何操作。应用程序中的close错误超出了您的控制范围。

-2

我想最好的方法是重试几次,每次尝试之间有一些短暂的延迟,然后记录问题并继续。

close()函数的手册页面提到EINTR可能是一个错误,这就是为什么重新尝试可以帮助解决问题。

如果你的程序即将退出,我不会太担心这种类型的错误检查,因为任何你分配的资源都将被操作系统释放(在大多数/典型的桌面/服务器平台上)。


感谢您的快速回复。我想确认我没有漏掉任何东西。 - zztops
1
至少在Linux上,调用close()多次似乎是一个不好的主意:https://lkml.org/lkml/2002/7/17/165 - alk
2
这是一个糟糕的想法。即使在close返回错误的操作系统中(这本身就是一个糟糕的想法),文件描述符也会在出错时关闭。再次调用close要么不起作用,要么关闭其他线程打开的不相关的文件描述符。 - Art
好吧,看起来我只能冒险一试,不进行错误检查了。 - zztops
@zztops:这绝对是最糟糕的解决方案。如果结果表明错误,请记录日志! - alk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接