如何检查文件描述符是否已关闭?

7 c low-level low-level-code low-level-io

在POSIX环境中使用系统调用来操作文本文件(open(), close(), read(), write())时,有没有办法检查我在使用时是否实际关闭了文件描述符close(file_descriptor)

示例:

int main(int argc, char **argv)
{
    int input_file; // file descriptor for input file
    int output_file; // file descriptor for output file
    input_file = open(argv[1], O_RDONLY));
    ouput_file = open(argv[2], ...file properties & permissions and crap.....);

    // blah blah blah...

    close(input_file);
    close(output_file);

    // what can I code here to check if the file descriptor was actually closed?
}
Run Code Online (Sandbox Code Playgroud)

Ser*_* L. 6

最简单的方法可能只是检查第一个的返回值close.

if (close(input_file)) {
    perror("close");
} else {
    // all good
}
Run Code Online (Sandbox Code Playgroud)

这是唯一的线程安全方式. 在一个多线程程序中,另一个线程可以获得一个新的文件描述符,它可以回收刚刚关闭的fd编号.


仅在单线程代码中,没有任何东西可以在close和check之间回收fd:

如果您希望检查文件描述符之后是否有效,那么您可以使用任何使用文件描述符的函数并检查它的错误代码.可能是最不干预和轻量级的fcntl/F_GETFL

if (fcntl(fd, F_GETFL) < 0 && errno == EBADF) {
    // file descriptor is invalid or closed
}
Run Code Online (Sandbox Code Playgroud)

你也可以close第二次打电话,它也可以失败EBADF.

if (close(fd) && errno == EBADF) {
    // file descriptor is invalid or closed
} else {
    // we successfully closed fd *now* (e.g. first close failed with EINTR)
    // or there was a different error
}
Run Code Online (Sandbox Code Playgroud)

close不会errno在成功时修改,但我们只errnoclose返回非零时读取,这意味着它已被设置.

  • 在多线程程序中要小心.文件描述符被重用.因此,关闭FD可能会导致另一个具有相同值的FD在"close()"之后立即打开 - 如果另一个线程进入并且非常快速地打开另一个文件.唯一的线程安全方法是检查返回值. (3认同)