【问题标题】:If close(2) fails with EIO, will the file descriptor still be deleted?如果 close(2) 因 EIO 失败,文件描述符是否仍会被删除?
【发布时间】:2011-11-09 22:51:53
【问题描述】:

如果 close(2) 系统调用因 EIO 失败,文件描述符是否仍会被删除?

如果是,是否不能通过稍后重试来处理虚假 IO 错误?如果不是,应该如何防止文件描述符泄漏?

【问题讨论】:

    标签: c unix posix system-calls


    【解决方案1】:

    这是一个棘手的问题。但是,POSIX 标准在close() 的描述中确实涵盖了它:

    如果 close() 被要捕获的信号中断,它应返回 -1 并将 errno 设置为 [EINTR] 并且 fildes 的状态未指定。如果在 close() 期间读取或写入文件系统时发生 I/O 错误,它可能会返回 -1 并将 errno 设置为 [EIO];如果返回此错误,则说明 fildes 的状态未指定。

    因此,标准未指定文件描述符的状态。

    对于大多数实际用途,它是封闭的;即使文件描述符正式打开,您也无能为力。您可以尝试一个无害的操作(如fcntl()F_GETFL)并查看您是否获得了EBADF,这表明描述符已正式关闭。但是,如果它是打开的并且 EIO 错误的原因是永久性的,那么您每次尝试对它执行任何操作时都可能会获得 EIO(可能包括 fcntl() 调用)。您可能会或可能不会得到另一个类似打开的操作返回的相同描述符。如果死文件描述符已打开但无法关闭,那么即使dup2() 是否可以成功地将“死”文件描述符指定为目标,也不清楚。

    【讨论】:

    • 如果您的程序是多线程的或使用信号处理程序,那么使用fcntl() 测试文件描述符可能不那么简单,因为它可能已被关闭然后重新用于其他用途。
    • 如果使用像 libuv 这样的非 stdio 框架会不会有问题?
    • 是的,这在任何使用open()close() 和亲属构建的框架中都是一个问题,所以除非libuv 使用与open()close() 不同的一组系统调用(这是非常不可能的),它可能会遇到close() 失败并使文件描述符处于不确定状态的问题。
    • 收到 EIO 后尝试再次关闭()文件描述符怎么样?
    • @MarcoPagliaricci:文件描述符的状态未指定。它可能已被关闭并且文件描述符被重用,因此重试可能正在关闭其他东西。很奇怪(而且不太可能),但确实如此。如果close() 失败,那么对文件描述符做任何事情确实是不安全的,除非可能报告问题发生了。
    猜你喜欢
    • 2021-05-08
    • 2013-09-13
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    相关资源
    最近更新 更多