linux编程dir类型变量,Linux 环境编程:dirfd参数 有关解析

本文详细介绍了Unix环境编程中at结尾函数如openat、mkfifoat等的dirfd参数,探讨了其在绝对路径和相对路径下的作用,以及如何利用dirfd实现基于文件描述符的路径定位。提供两种使用方法和实际代码示例,帮助理解这一高级特性。
摘要由CSDN通过智能技术生成

背景

在Unix环境编程中,系统提供了很多以at结尾的函数,如openat、fstatat等,而这类函数通常有一个特点,就是形参列表中多了int dirfd

例如:

int open(const char *pathname, int flags, mode_t mode);

int openat(int dirfd, const char *pathname, int flags, mode_t mode);

int mkfifo(const char *pathname, mode_t mode);

int mkfifoat(int dirfd, const char *pathname, mode_t mode);

...

意义

dirfd参数的意义:

1)path参数指定为绝对路径名时,fd会被忽略,openat函数就相当于open函数

2)path参数指定为相对路径名时,fd参数指出了相对路径名在文件系统的开始地址。fd参数是通过打开相对路径名所在的目录来获取。所以此时的path是相对于文件描述符dirfd所引用的目录。

3)path参数指定了相对路径名,并且fd参数是特殊值AT_FDCWD。在这种情况下,路径名在当前工作目录中获取,openat函数在操作上与open函数类似。

实际上,dirfd参数 实现了 以 文件描述符+相对路径 作为定位的 一种功能(而不是 当前工作路径+相对路径 作为定位)。我们可以参考下文的文档描述来体会这个功能:

If the pathname given in pathname is relative, then it is interpreted relative to the directory referred to by the file descriptor dirfd (rather than relative to the current working directory of the calling process, as is done by mkfifo() for a relative pathname).

如果pathname中给定的路径名是相对的,那么它将被解释为相对于文件描述符dirfd所引用的目录(而不是相对于调用进程的当前工作目录)。

用法

用法有两种,分别说明如下:

1、直接用open打开目录,用返回值作为openat的第一个参数的值,代码如下:

#include

#include

#include

#include

#include

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);

if (dir_fd < 0)

{

perror("open");

exit(EXIT_FAILURE);

}

flags = O_CREAT | O_TRUNC | O_RDWR | O_DIRECTORY;

mode = 0640;

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("./open", "log.txt");

return 0;

}

**2、借用dirfd,将DIR*转换成int类型的文件描述符 **

#include

#include

int dirfd(DIR *dirp);

完整代码如下:

#include

#include

#include

#include

#include

int main()

{

DIR *dir;

int dirfd2;

int fd;

int n;

dir = opendir("./open/chl");

if(NULL == dir)

{

perror("open dir error");

return -1;

}

dirfd2 = dirfd(dir);

if(-1 == dirfd2)

{

perror("dirfd error");

return -1;

}

fd = openat(dirfd2,"output.log",O_CREAT|O_RDWR|O_TRUNC);

if(-1 == fd)

{

perror("opeat error");

return -1;

}

n = write(fd,"Hello world!

",15);

close(fd);

closedir(dir);

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值