open()与openat()区别

从Linux2.6.16开始,引用了openat函数。主要解决两个问题:

  1. 让线程可以使用相对路径名打开目录中的文件,不再是只能打开当前目录中的文件。同一进程中的所有线程共享当前目录,很难让同一进程中的线程工作在不同目录。
  2. 避免time-of-check-to-time-of-use(TOCTTOU)错误。如果有两个基于文件的函数调用,并其中一个依赖另一个的结果,这个程序是脆弱的。这两个调用都不是原子操作,在两个函数调用期间,可能文件发生了变化,进而导致影响最终结果。文件系统命名空间中的TOCTTOU错误通常处理那些特权程序降低特权文件的权限控制或通过特权文件打开一个安全漏洞等方式进行。
#include <fcntl.h>
int open(int const char* pathname, int flags);
int open(int const char* pathname,int flags, mode_t mode);
int openat(int dirfd, const char *pathname, int flags);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);

相比之下,openat函数多了一个dirfd参数:

  1. 如果pathname指定的是绝对路径名。这种情况下,dirfd参数将被忽略,openat函数等同于open函数。
  2. 如果pathname指定的是相对路径,并且dirfd的值不是AT_FDCWD,pathname则参照dirfd指定的目录下寻找,dirfd可以是当前目录(打开的是当前目录),也可以其他目录。dirfd是通过open函数打开相对路径名所在的目录来获取的。
  3. 如果pathname指定相对路径名,并且dirfd的值为AT_FDEWD时,相对路径名在当前目录获取(相当于当前目录的相对路径)。
#include <stdio.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <stdlib.h>  
#include <unistd.h>  
  
void creat_at(char *dir_path, char *relative_path)  
{  
    int dir_fd;  
    int fd;  
    int flags;  
    mode_t mode;  
  
    dir_fd = open(dir_path, O_RDONLY);  //fd参数是通过打开相对路径名所在的目录来获取。
    if (dir_fd < 0)   
    {  
        perror("open");  
        exit(EXIT_FAILURE);  
    }  
  
    flags = O_CREAT | O_TRUNC | O_RDWR;  
    mode = 0640;  //-rw-r-----
    fd = openat(dir_fd, relative_path, flags, mode);  
    if (fd < 0)   
    {  
        perror("openat");  
        exit(EXIT_FAILURE);  
    }  
  
    write(fd, "HELLO", 5);  
  
    close(fd);  
    close(dir_fd);  
}  
  
int main()  
{  
    creat_at("../03.文件IO", "log.txt");  
    return 0;  
}

借用dirfd函数,讲DIR*转换成int (文件描述符)

#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <dirent.h>  
#include <stdio.h>  
#include <unistd.h>  
  
int main()  
{  
    DIR *dir;  
    int dirfd2;  
    int fd;  
    int n;  
  
    dir = opendir("../03.文件IO");  
    if(NULL == dir)  
    {  
        perror("open dir error");  
        return -1;  
    }  
    dirfd2 = dirfd(dir);  //返回参数dirp所指向的目录文件的文件描述符
    if(-1 == dirfd2)  //转换失败返回-1.并且设置error变量
    {  
        perror("dirfd error");  
        return -1;  
    }  
  
    fd = openat(dirfd2,"output.log",O_CREAT|O_RDWR|O_TRUNC, \
                      S_IRWXU|S_IRWXG|S_IRWXO);  
    if(-1 == fd)  
    {  
        perror("opeat error");  
        return -1;  
    }  
    n = write(fd,"Hello world!\n",15);  //write 返回实际写入的字符数,失败则返回-1
      
    close(fd);  
    closedir(dir);  
  
    return 0;  
  
}

以上是在学习Unix编程中遇到的open和openat函数的一点笔记,希望大佬们能补充纠正,谢谢。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值