CLOSE - Linux手册页

时间:2019-08-20 17:58:36  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2020-06-09

名称

close-关闭文件描述符

语法

#include <unistd.h>

int close(int fd);

说明

close()关闭文件描述符,以便它不再引用任何文件,并且可以重用。与该进程关联并由该进程拥有的文件上保留的所有记录锁定(请参阅fcntl(2))(无论用于获取该锁定的文件描述符如何)都将被删除。

如果fd是引用基础打开文件描述的最后一个文件描述符(请参见open(2)),则释放与打开文件描述相关的资源;如果文件描述符是对使用unlink(2)删除的文件的最后引用,则该文件将被删除。

返回值

如果成功,close()返回零。如果出错,则返回-1,并正确设置errno。

错误说明

EBADF
fd不是有效的打开文件描述符。
EINTR
close()调用被信号中断;参见signal(7)。
EIO
发生I / O错误。
ENOSPC, EDQUOT
在NFS上,通常不会针对超出可用存储空间的第一个写入报告这些错误,而是针对随后的write(2),fsync(2)或close()报告这些错误。

请参阅注释,以获取有关为什么错误后不应重试close()的讨论。

遵循规范

POSIX.1-2001,POSIX.1-2008,SVr4、4.3BSD。

备注

成功关闭并不能保证数据已成功保存到磁盘,因为内核使用缓冲区高速缓存来推迟写入。通常,关闭文件时,文件系统不会刷新缓冲区。如果需要确保数据实际存储在基础磁盘上,请使用fsync(2)。 (这将取决于磁盘硬件。)

close-on-exec文件描述符标志可用于确保成功执行execve(2)时自动关闭文件描述符。有关详细信息,请参见fcntl(2)。

Multithreaded processes and close()

当文件描述符在同一进程中的其他线程中被系统调用使用时,关闭文件描述符可能是不明智的。由于文件描述符可能会被重用,因此有些模糊的竞争条件可能会导致意外的副作用。

此外,请考虑以下情形,其中两个线程正在同一文件描述符上执行操作:

1.
在文件描述符的I / O系统调用中阻塞了一个线程。例如,它正在尝试将(2)写入已满的管道,或者试图从当前没有可用数据的流套接字读取(2)。
2.
另一个线程关闭文件描述符。

在这种情况下,行为在不同系统之间会有所不同。在某些系统上,当文件描述符关闭时,阻塞的系统调用将立即返回错误。

在Linux(可能还有其他一些系统)上,行为是不同的。阻塞的I / O系统调用将保留对基础打开文件描述的引用,并且该引用将使描述保持打开状态,直到I / O系统调用完成。 (有关打开文件描述的讨论,请参见open(2)。)因此,第一个线程中的阻塞系统调用可能在第二个线程中的close()之后成功完成。

Dealing with error returns from close()

仔细的程序员将检查close()的返回值,因为很有可能仅在释放打开文件描述的最终close()上报告先前write(2)操作的错误。关闭文件时未检查返回值可能会导致数据无提示丢失。使用NFS和磁盘配额尤其可以观察到这一点。

但是请注意,故障返回仅应用于诊断目的(即,警告应用程序可能仍存在I / O挂起或I / O可能已失败)或补救目的(例如,编写再次创建文件或创建备份)。

在失败返回之后重试close()是错误的事情,因为这可能导致另一个线程的重用文件描述符被关闭。发生这种情况是因为Linux内核总是在关闭操作的早期释放文件描述符,将其释放以供重用。仅在稍后的关闭操作中才会发生可能返回错误的步骤,例如将数据刷新到文件系统或设备。

同样,许多其他实现总是关闭文件描述符(除了EBADF以外,这意味着文件描述符无效),即使它们随后在从close()返回时报告错误。 POSIX.1目前在这一点上保持沉默,但是计划在标准的下一个主要版本中强制要求这种行为。

一位想了解I / O错误的细心程序员可以在close()之前调用fsync(2)。

EINTR错误是一种特殊情况。关于EINTR错误,POSIX.1-2008说:

如果close()被要捕​​获的信号中断,则它将返回-1,并将errno设置为EINTR,并且未指定fildes的状态。

这允许出现在Linux和许多其他实现上的行为,其中与close()可能报告的其他错误一样,保证文件描述符是关闭的。但是,它也允许另一种可能性:该实现返回EINTR错误并保持文件描述符为打开状态。 (根据其文档,HP-UX的close()执行此操作。)然后,调用方必须再次使用close()关闭文件描述符,以避免文件描述符泄漏。实现行为上的这种差异为便携式应用程序提供了一个困难的障碍,因为在许多实现中,在EINTR错误之后一定不能再次调用close(),而在至少一个实现上,必须再次调用close()。计划解决POSIX.1标准的下一个主要版本的难题。

另外参见

fcntl(2),fsync(2),open(2),shutdown(2),unlink(2),fclose(3)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/