如果调用close(2)系统调用返回EIO错误,那么文件描述符是否会被删除?
如果是的话,难道不可能通过稍后重试来处理偶发的IO错误吗?如果不是,那该怎么防止文件描述符泄露呢?
如果调用close(2)系统调用返回EIO错误,那么文件描述符是否会被删除?
如果是的话,难道不可能通过稍后重试来处理偶发的IO错误吗?如果不是,那该怎么防止文件描述符泄露呢?
这是一个棘手的问题。然而,POSIX标准在 close()
的描述中涵盖了它:
如果 close() 被要捕获的信号中断,它将返回-1,并将errno设置为[EINTR],fildes的状态未指定。如果在close()期间从文件系统读取或写入时发生I/O错误,则可能会返回-1,并将errno设置为[EIO];如果返回此错误,则fildes的状态未指定。
因此,文件描述符的状态未由标准指定。
对于大多数实际用途来说,它是关闭的;即使它正式打开,你也几乎无法使用文件描述符。你可以尝试一个无害的操作(如 fcntl()
和 F_GETFL
),看看是否会收到EBADF回复,表示描述符已经被正式关闭。但是,如果它是打开的,并且EIO错误的原因是永久性的,则每次尝试对其执行任何操作(包括 fcntl()
调用)时都可能会得到EIO。你可能永远不会获得另一个类似open的操作返回相同的描述符。如果死的文件描述符是打开但无法关闭的,则甚至不清楚使用dup2()指定“死”文件描述符作为目标是否能够成功。
fcntl()
测试文件描述符可能并不直接,因为它可能已关闭,然后被重新用于其他用途。 - mark4oopen()
、close()
及其相关函数构建的任何框架都会遇到的问题,因此除非libuv
使用与open()
和close()
不同的系统调用集(这相当不可能),否则它可能会遭受close()
失败并使文件描述符处于不确定状态的问题。 - Jonathan Lefflerclose()
失败,除了报告问题发生之外,对文件描述符执行任何操作都不安全。 - Jonathan Leffler