3.2 文件描述符

文件描述符 0,1,2 分别表示标准输入,标准输出,标准错误,STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO

3.3 open, openat

open/openat 函数可以打开或者创建一个文件。

#include <fcntl.h>

int open(const char *path, int oflag, ...);
int openat(int fd, const char *path, int oflag, ...);

path 是要打开或创建文件的名字,oflag 的选项有:

下面五个选项是互斥的,只能选择一个:

  • O_RDONLY 只读打开
  • O_WRONLY 只写打开
  • O_RDWR 读写打开
  • O_EXEC 只执行打开
  • O_SEARCH 只搜索打开 (应用于目录)

下面的选项是可选的

  • O_APPEND
  • O_CLOEXEC
  • O_CREAT
  • O_DIRECTORY
  • O_EXCL
  • O_NOCTTY
  • O_NOFOLLOW
  • O_NONBLOCK
  • O_SYNC
  • O_TRUNC 如果此文件存在,而且为只写或读写打开,则将其长度截断为 0.
  • O_TTY_INIT
  • O_DSYNC
  • O_RSYNC

openopenat 函数的区别在于 fd 参数。

  • path 是绝对路径名,那么 fd 被忽略,openat 相当于 open 函数。
  • path 是相对路径名,fd 指出了相对路径名在文件系统中的开始地址,fd 是通打开相对路径名所在的目录获取的。
  • path 是相对路径名,fd 是特殊值 AT_FDCWD,这种情况下,路径名在当前工作目录获取。

3.4 creat

create 可以创建一个新文件。

#include <fcntl.h>

int creat(const char *path, mode_t mode);

等效于 open(path, O_WRONLY | O_CREAT | O_TRUNC, mode)

3.5 close

close 函数关闭一个打开的文件。

#include <unistd.h>

int close(int fd);

当一个进程终止时,内核会自动关闭它所有打开的文件。

3.6 lseek

lseek 显式设置文件偏移量,当打开一个文件,除非指定

3.12 dup, dup2

用来复制一个现有的文件描述符:

int dup(int fd);
int dup2(int fd, int fd2);

dup 返回的文件描述符是当前可用的文件描述符的最小值。
dup2 可以用 fd2 指定新描述符的值,如果 fd2 已经打开,则先将其关闭。如果 fd==fd2,那么直接返回 fd。

执行 dup 函数后,有两个 fd 指向文件表项。

dup(fd) 等价于 fcntl(fd, F_DUPFD, 0)

dup2(fd, fd2) 等价于 close(fd2) + fcntl(fd, F_DUPFD, fd2), 不过 dup2 是原子操作。

3.13 sync, fsync, fdatasync

磁盘 io 一般有缓冲区来实现延迟写,这三个函数用来保证磁盘上的内容和缓冲区一致。

int fsync(int fd);
int fdatasync(int fd);
void sync();
  • sync: 只将所有修改过的缓冲区排入写队列,立即返回,不会阻塞等待磁盘操作结束。update 系统守护进程一般每 30s 就会调用一次 sync 函数。
  • fsync: 只对某个 fd 生效,并且会阻塞等待磁盘操作完成。
  • fdatasync: 和 fsync 类似,不过只影响数据部分。而 fsync 还会同步更新文件的属性。

3.14 fcntl

fcntl 用来改变已打开文件的属性。

int fcntl(int fd, int cmd, ...); /* int arg */

有五种功能:

  • 复制一个已有的描述符 (cmd = F_DUPFD 或 F_DUPFD_CLOEXEC)

3.15 ioctl

3.16 /dev/fd