【发布时间】:2011-11-09 22:51:53
【问题描述】:
如果 close(2) 系统调用因 EIO 失败,文件描述符是否仍会被删除?
如果是,是否不能通过稍后重试来处理虚假 IO 错误?如果不是,应该如何防止文件描述符泄漏?
【问题讨论】:
标签: c unix posix system-calls
如果 close(2) 系统调用因 EIO 失败,文件描述符是否仍会被删除?
如果是,是否不能通过稍后重试来处理虚假 IO 错误?如果不是,应该如何防止文件描述符泄漏?
【问题讨论】:
标签: c unix posix system-calls
这是一个棘手的问题。但是,POSIX 标准在close() 的描述中确实涵盖了它:
如果 close() 被要捕获的信号中断,它应返回 -1 并将 errno 设置为 [EINTR] 并且 fildes 的状态未指定。如果在 close() 期间读取或写入文件系统时发生 I/O 错误,它可能会返回 -1 并将 errno 设置为 [EIO];如果返回此错误,则说明 fildes 的状态未指定。
因此,标准未指定文件描述符的状态。
对于大多数实际用途,它是封闭的;即使文件描述符正式打开,您也无能为力。您可以尝试一个无害的操作(如fcntl() 和F_GETFL)并查看您是否获得了EBADF,这表明描述符已正式关闭。但是,如果它是打开的并且 EIO 错误的原因是永久性的,那么您每次尝试对它执行任何操作时都可能会获得 EIO(可能包括 fcntl() 调用)。您可能会或可能不会得到另一个类似打开的操作返回的相同描述符。如果死文件描述符已打开但无法关闭,那么即使dup2() 是否可以成功地将“死”文件描述符指定为目标,也不清楚。
【讨论】:
fcntl() 测试文件描述符可能不那么简单,因为它可能已被关闭然后重新用于其他用途。
open()、close() 和亲属构建的框架中都是一个问题,所以除非libuv 使用与open() 和close() 不同的一组系统调用(这是非常不可能的),它可能会遇到close() 失败并使文件描述符处于不确定状态的问题。
close() 失败,那么对文件描述符做任何事情确实是不安全的,除非可能报告问题发生了。