open与openat的区别
Linux 中的 open 和 openat 系统调用都用于打开文件,但它们有一些区别。
一、函数原型
open 系统调用的原型
#include <fcntl.h>
int open(const char *pathname, int flags, mode_t mode);
- pathname 是要打开的文件路径
- flags 是打开文件的标志
- mode 是文件的权限。
open 系统调用会在文件系统中查找 pathname 指定的文件,并返回一个文件描述符,用于后续的读写操作。
openat 系统调用的原型
#include <fcntl.h>
int openat(int dirfd, const char *pathname, int flags, mode_t mode);
- dirfd 是一个文件描述符
- pathname 是相对于 dirfd 的路径
- flags 和 mode 的含义与 open 系统调用相同。
openat 系统调用会在 dirfd 指定的目录下查找 pathname 指定的文件,并返回一个文件描述符。
二、openat使用场景
openat
系统调用相对于 open
系统调用的优势在于,它可以避免一些安全问题。在多线程或多进程环境中,使用 open
系统调用打开文件时,可能会存在竞态条件,导致打开的文件不是预期的文件。而使用 openat
系统调用,可以避免这个问题,因为它是基于一个已经打开的目录文件描述符进行查找的,不需要再次查找文件路径。
此外,openat 系统调用还可以用于打开相对于某个符号链接的路径的文件,而 open 系统调用则不能。
https://www.cnblogs.com/BinBinStory/p/7400993.html
引入openat
是方便一个进程内的各线程可拥有不同的当前目录,使用chdir
会影响整个进程,而使用openat
只需要每个线程在初始化时打开一个目录获得dirfd
(调用open
),然后就可以openat
在“当前目录”操作文件了,如下伪代码所示:
int dirfd = open("/tmp"); // 相当于chdir到“/tmp”
int filefd = openat(dirfd, "myfile"); // 在/tmp目录下打开“myfile”文件 。
At means that the working directory considered for the open call is at the given file descriptor, passed as the parameter. The *at() family of functions are useful so that all path relative operations refer to the same file inode, even if it changes name or someone replaces it.
个人觉得这句话靠谱,at
一直以相对路径来读取文件信息,相对于绝对路劲,当文件换了一个路径时:
- 程序中需要读写该路径下的多个文件,如果使用
open
实现,那么需要修改程序中所有open
文件的绝对路径。 - 使用
openat
,只需要修改传入参数dirfd
即可,也就是修改文件夹路径。