创建和除去文件
此部分描述了创建、打开、关闭或除去文件时由操作系统执行的内部过程。
创建文件
不同的子例程创建特定类型的文件,如下所示:
| 子例程 | 所创建文件的类型 |
|---|---|
| 创建 | 常规 |
| 打开 | 常规(设置了 O_CREAT 标记时) |
| mknod | 常规、先进先出 (FIFO) 或特殊 |
| mkfifo | 命名管道 (FIFO) |
| 管道 | 未命名管道 |
| 套接字 | 套接字 |
| mkdir | 目录 |
| 符号链接 | 符号链接 |
创建常规文件(creat、open 或 mknod 子例程)
使用 creat 子例程根据 Pathname 和 Mode 参数中设置的值创建文件。 如果 Pathname 参数中命名的文件存在并且进程对文件具有写许可权,creat 子例程截断文件。 截断将释放所有数据块并将文件大小设置为 0。 还可以使用带有 O_CREAT 标志的 open 子例程来创建新的常规文件。
使用 creat创建的文件, mkfifo, 或 mknod 子例程获取在 Mode 参数中设置的访问许可权。 使用 open 子例程创建的常规文件从 O_CREAT 标记 Mode 参数获取它们的访问方式。 umask 子例程为进程创建的新文件设置文件方式创建掩码 (访问方式集) ,并返回掩码的先前值。
新创建文件上的许可权位是 umask 位取反后与由创建进程设置的文件创建方式位进行“与”操作的结果。 进程创建新文件时,操作系统执行下列操作:
- 确定创建进程的许可权
- 检索合适的 umask 值
- 反转 umask 值
- 使用“与”操作将创建进程的许可权与 umask 值的取反组合
创建特殊文件(Mknod 或 mkfifo 子例程)
可以使用 mknod 和 mkfifo 子例程创建新的特殊文件。 mknod 子例程处理命名管道 (FIFO),一般还处理设备文件。 它为与由 creat 子例程所创建文件相同的文件创建索引节点。 使用 mknod 子例程时,文件类型字段被设置来指示正在创建的文件的类型。 如果文件是块或字符类型设备文件,主要和次要设备的名称被写入索引节点中。
mkfifo 子例程是 mknod 子例程的接口,用于创建命名管道。
打开文件
open 子例程是进程访问现有文件所需的第一步。 Open 子例程返回一个文件描述符。 读、写、搜索、复制、设置 I/O 参数、确定文件状态和关闭文件都使用由 open 调用返回的文件描述符。 分配文件描述符时,open 子例程为文件描述符表中的文件创建条目。
Open 子例程执行下列操作:
- 检查是否存在合适的许可权允许进程访问文件。
- 在文件描述符表中为打开的文件分配一个条目。 Open 子例程将初始读/写字节偏移量设为 0(文件的开始处)。
ioctl 或 ioctlx 子例程对打开的特殊设备文件执行控制操作。
关闭文件
当进程不再需要访问打开的文件时, close 子例程从表中除去该文件的条目。 如果多于一个文件描述符引用文件的文件表条目,文件的引用计数减少 1 并且关闭完成。 如果文件只有一个对其的引用,文件表条目被释放。 进程试图使用断开连接的文件描述符会导致错误,直到另一个 open 子例程为该文件描述符值再分配一个值。 进程退出时,内核检查其激活的用户文件描述符并内部关闭每个描述符。 此操作保证进程结束之前关闭所有文件。
除去文件
不再需要某个文件时,可以使用 unlink 子例程来从包含指定文件的目录中将其除去。 如果存在指向同一文件的多个硬链接,那么 unlink 子例程将除去指定的链接。 如果只存在一个链接,那么 unlink 子例程将除去该文件本身。 有关更多信息,请参阅 unlink 子例程。