文件描述符和文件的关系
内核维护的与文件相关的三个数据结构
- 进程级的文件描述符表
- 系统级的打开文件表
- 文件系统的i-node表
进程级的文件描述符(open file descriptor )表
内核为了维护进程,会针对每个进程打开一个文件的描述符表(体现了Linux一切皆文件的思想)。该表的每一项都记录了单个文件的描述符的相关信息,如下所示:
- 控制描述符操作的一组标志。(目前只有clsoe-on-exec, 调用exec时关闭打开的文件,exec调用失败保持文件打开的状态)
- 对打开的文件句柄的引用。
系统级的打开文件表(open file table)
内核会对打开的所有的文件维护一张系统级的描述表格,称之为打开文件表,并将表中的各条目称之为打开文件句柄(open file handle)。一个打开的文件句柄存储了与一个打开文件相关的所有信息:
- 当前文件偏移量(open() 、write()时更新, lseek()直接修改)
- 打开文件时所使用的状态标识(open()的flag参数)
- 文件的访问模式(只读,只写,读写)
- 与信号驱动相关的设置
- 对该文件i-node对象的引用
文件系统分i-node表
每个文件都会为驻留其上的所有文件建立一个i-node表,每个文件的i-node信息如下:
- 文件类型(常规文件、套接字、FIFO)和访问权限
- 一个指针,只想该文件所持有的锁的列表
- 文件的各种属性,包括问阿金大小以及与不同类型操作相关的时间戳
i-node与文件一一对应
两个要点:
- 两个不同的文件描述符,不管是不是属于同一个进程,如果都指向同一个打开文件句柄,那么这两个文件描述符将共享同一个文件偏移量
- 要获取和修改 打开的文件标志(例如,O_APPEND、O_NONBLOCK、O_ASYNC),可以执行fcntl()的F_GETFL和F_SETFL操作。
- 文件描述符标志(close-on-clsoe标志)为进程和文件描述符所私有。