创建和除去文件

此部分描述了创建、打开、关闭或除去文件时由操作系统执行的内部过程。

创建文件

不同的子例程创建特定类型的文件,如下所示:

子例程 所创建文件的类型
创建 常规
打开 常规(设置了 O_CREAT 标记时)
mknod 常规、先进先出 (FIFO) 或特殊
mkfifo 命名管道 (FIFO)
管道 未命名管道
套接字 套接字
mkdir 目录
符号链接 符号链接

创建常规文件(creat、open 或 mknod 子例程)

使用 creat 子例程根据 PathnameMode 参数中设置的值创建文件。 如果 Pathname 参数中命名的文件存在并且进程对文件具有写许可权,creat 子例程截断文件。 截断将释放所有数据块并将文件大小设置为 0。 还可以使用带有 O_CREAT 标志的 open 子例程来创建新的常规文件。

使用 creat创建的文件, mkfifo, 或 mknod 子例程获取在 Mode 参数中设置的访问许可权。 使用 open 子例程创建的常规文件从 O_CREAT 标记 Mode 参数获取它们的访问方式。 umask 子例程为进程创建的新文件设置文件方式创建掩码 (访问方式集) ,并返回掩码的先前值。

新创建文件上的许可权位是 umask 位取反后与由创建进程设置的文件创建方式位进行“与”操作的结果。 进程创建新文件时,操作系统执行下列操作:

  • 确定创建进程的许可权
  • 检索合适的 umask
  • 反转 umask
  • 使用“与”操作将创建进程的许可权与 umask 值的取反组合

创建特殊文件(Mknod 或 mkfifo 子例程)

可以使用 mknodmkfifo 子例程创建新的特殊文件。 mknod 子例程处理命名管道 (FIFO),一般还处理设备文件。 它为与由 creat 子例程所创建文件相同的文件创建索引节点。 使用 mknod 子例程时,文件类型字段被设置来指示正在创建的文件的类型。 如果文件是块或字符类型设备文件,主要和次要设备的名称被写入索引节点中。

mkfifo 子例程是 mknod 子例程的接口,用于创建命名管道。

打开文件

open 子例程是进程访问现有文件所需的第一步。 Open 子例程返回一个文件描述符。 读、写、搜索、复制、设置 I/O 参数、确定文件状态和关闭文件都使用由 open 调用返回的文件描述符。 分配文件描述符时,open 子例程为文件描述符表中的文件创建条目。

Open 子例程执行下列操作:

  • 检查是否存在合适的许可权允许进程访问文件。
  • 在文件描述符表中为打开的文件分配一个条目。 Open 子例程将初始读/写字节偏移量设为 0(文件的开始处)。

ioctlioctlx 子例程对打开的特殊设备文件执行控制操作。

关闭文件

当进程不再需要访问打开的文件时, close 子例程从表中除去该文件的条目。 如果多于一个文件描述符引用文件的文件表条目,文件的引用计数减少 1 并且关闭完成。 如果文件只有一个对其的引用,文件表条目被释放。 进程试图使用断开连接的文件描述符会导致错误,直到另一个 open 子例程为该文件描述符值再分配一个值。 进程退出时,内核检查其激活的用户文件描述符并内部关闭每个描述符。 此操作保证进程结束之前关闭所有文件。

除去文件

不再需要某个文件时,可以使用 unlink 子例程来从包含指定文件的目录中将其除去。 如果存在指向同一文件的多个硬链接,那么 unlink 子例程将除去指定的链接。 如果只存在一个链接,那么 unlink 子例程将除去该文件本身。 有关更多信息,请参阅 unlink 子例程。