Linux 环境编程:dirfd参数 有关解析
背景
在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 <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);
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 <sys/types.h>
#include <dirent.h>
int dirfd(DIR *dirp);
完整代码如下:
#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("./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!\n",15);
close(fd);
closedir(dir);
return 0;
}
Linux 环境编程:dirfd参数 有关解析的更多相关文章
- Linux环境编程相关的文章
Linux环境编程相关的文章 好几年没有接触Linux环境下编程了,好多东西都有点生疏了.趁着现在有空打算把相关的一些技能重拾一下,顺手写一些相关的文章加深印象. 因为不是写书,也受到许多外部因素限制 ...
- Linux移植之tag参数列表解析过程分析
在Linux移植之内核启动过程start_kernel函数简析中已经指出了start_kernel函数的调用层次,这篇主要是对具体的tag参数列表进行解析. 1.内存参数ATAG_MEM参数解析 2. ...
- Linux环境编程进程间通信机制理解
一.Linux系统调用主要函数 二.创建进程 1.创建子进程系统调用fork() 2.验证fork()创建子进程效果 3.系统调用fork()与挂起系统调用wait() 三.模拟进程管道通信 四.pi ...
- Linux环境编程--waitpid与fork与execlp
waitpid waitpid(等待子进程中断或结束) 表头文件 #include<sys/types.h> #include<sys/wait.h> 定义函数 pid_t w ...
- Linux环境编程导引
计算机系统硬件组成 总线 贯穿整个系统的一组电子管道称为总线, 分为: 片内总线 系统总线 数据总线DB 地址总线AB 控制总线CB 外部总线 I/O设备 I/O设备是系统与外界联系的通道 键盘鼠标是 ...
- Linux网络编程六、报文解析(1)
一.pcap文件解析 依赖的库:libpcap,头文件:pcap/pcap.h 获取pcap文件:tcpdump,-i:指定监听接口,默认配置好的最小的号码的接口.-w:指定存入文件,将原始报文存入指 ...
- Linux环境下vsftpd参数配置
很久之前就用过vsftpd,但总是忘了参数该如何配置,今天特地有搜索了一遍,把配置方法整理如下: (1)检查是否已安装vsftpd #rpm -qa | grep vsftpd vsftpd--.el ...
- 笔记整理:计算CPU使用率 ----linux 环境编程 从应用到内核
linux 提供time命令统计进程在用户态和内核态消耗的CPU时间: [root@localhost ~]# time sleep real 0m2.001s user 0m0.001s sys 0 ...
- Linux下ping命令参数详细解析
-a Audible ping. #Audible ping. -A Adaptive ping. Interpacket interval adapts to round-trip time, so ...
随机推荐
- Mybatis 插件原理解析
SqlSessionFactory 是 MyBatis 核心类之一,其重要功能是创建 MyBatis 的核心接口 SqlSession.MyBatis 通过 SqlSessionFactoryBuil ...
- sqli-labs第三关 详解
通过第二关,来到第三关 我们用了前两种方法,都报错,然后自己也不太会别的注入,然后莫名的小知识又增加了.这居然是一个带括号的字符型注入, 这里我们需要闭合前面的括号. $sql=select * fr ...
- 题解【QTree3】
题目描述 给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白 有两种操作: 0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑) 1 v : 询问1到v的路径上的第一个黑点,若无,输出 ...
- 极客 Play 玩 Terminal——GitHub 热点速览 Vol.40
作者:HelloGitHub-小鱼干 多少人以为暗黑的终端便是一名程序员的工作台,其实上,终端可以不只是一个输入 command 的界面,也可以是本周特推 kb 一样,面向极客的极简命令行知识库管理器 ...
- 创建好maven项目以后发现无法创建scala文件
今天创建了一个maven项目 然后准备创建scala文件的时候发现没有Scala 然后只好上网上找方法了 下面是一种解决方法 1.点击file,选择settings 进去之后,选择build 进去 ...
- 抓包工具Charles使用
设置Reason:最近接触一个APP后台项目,但是不知道APP各个操作访问对应的是后台的哪个接口,迫切需要使用一个抓包工具one by one Charles Free 简单上手快,首选 下载:h ...
- golang通过cgo调用lua
目录 1.前期准备 2.测试go代码 3.完成的一个学习项目 4.总结 1.前期准备 1.第三方库:https://github.com/aarzilli/golua 2.下载lua源码:https: ...
- 如何把C++的源代码改写成C代码?而C改C++只需一步!
★ 如何把C++的源代码改写成C代码? C++解释器比C语言解释器占用的存储空间要大,想要在某些特定场合兼容C++代码,同时为了节省有限的存储空间,降低成本,也为了提高效率,将用C++语言写的源程序用 ...
- linux(centos8):安装Jenkins持续集成工具(java 14 / jenkins 2.257)
一,什么是Jenkins? 1,jenkins是什么? Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具, 用于监控持续重复的工作,旨在提供一个开放易用的软件平台, 使软件的持续 ...
- RocketMQ单节点搭建
RocketMQ服务搭建 下载RocketMQ源码: http://mirror.bit.edu.cn/apache/rocketmq/4.4.0/rocketmq-all-4.4.0-source- ...