本节书摘来自异步社区《Linux系统编程(第2版)》一书中的第2章,第2.6节,作者:【美】Robert Love著,更多章节内容可以访问云栖社区“异步社区”公众号查看
2.6 关闭文件
当程序完成对某个文件的操作后,可以通过系统调用close()取消文件描述符到对应文件的映射:
系统调用close()会取消当前进程的文件描述符fd与其关联的文件之间的映射。调用后,先前给定的文件描述符fd不再有效,内核可以随时重用它,当后续有open()调用或creat()调用时,重新把它作为返回值。close()调用在成功时返回0,出错时返回-1,并相应设置errno值。close()的用法很简单:
值得一提的是,关闭文件操作并非意味着该文件的数据已经被写到磁盘。如果应用希望保证关闭文件之前数据已经写入磁盘,它需要使用先前在2.4节中讨论的同步选项。
关闭文件虽然操作上很简单,但是也会带来一些影响。当关闭指向某个文件的最后一个文件描述符时,内核中表示该文件的数据结构就释放了。如果释放了数据结构,会清除和文件相关的索引节点的内存拷贝。如果已经没有内存和索引节点关联,该索引节点也会被从内存中清除(出于性能考虑,也可能会保存在内核中,但也可能不需要)。如果文件已经从磁盘上解除链接,但是解除之前还一直打开,在文件被关闭并且其索引节点从内存中删除之后,该文件才会真正从物理磁盘上删除。因此,调用close()可能会使得一个已解除链接的文件最终从磁盘上删除。
错误码
一个常见的错误是没有检查close()的返回值。这样做可能会遗漏严重错误,因为延迟操作相关的错误可能到了后期才出现,而close()的返回值早就给出了这些错误信息。在失败时,有很多可能的errno值。除了EBADF(给定的文件描述符不合法),最重要的错误码是EIO,表示底层I/O错误,该错误很可能和实际的close操作并不相关。如果忽略出现的错误,在合法情况下,文件描述符总是关闭的,而且相关的数据结构也都释放了。
close()调用绝不会返回EINTR,虽然POSIX标准允许。Linux内核开发者可能很清楚,返回EINTR并不合适。