当前位置: 首页 > news >正文

fopen 函数实现追踪(glibc 2.9)(了解和选学)

目录

一、下载源码

二、源码分析:从 fopen 到系统调用

(1) fopen 的入口宏定义

(2) _IO_new_fopen 函数

(3) __fopen_internal 函数

(4) _IO_new_file_fopen 函数

(5) _IO_file_open 函数

(6) __open 系统调用封装

(7) INLINE_SYSCALL 宏

(8) INTERNAL_SYSCALL 宏(x86-64 架构)

三、总结:fopen 的完整调用链

四、关键细节说明

五、伪代码简化


一、下载源码

可通过以下镜像站获取 glibc 2.9 源码:

中国科学技术大学镜像站:https://mirrors.ustc.edu.cn/gnu/libc/

清华大学镜像站:https://mirrors.tuna.tsinghua.edu.cn/gnu/libc/


二、源码分析:从 fopen 到系统调用

(1) fopen 的入口宏定义

#define _IO_new_fopen fopen  // 宏定义,确保兼容性

实际调用的是 _IO_new_fopen,这是 glibc 内部实现的入口。

(2) _IO_new_fopen 函数

_IO_FILE *
_IO_new_fopen (const char *filename, const char *mode) {return __fopen_internal(filename, mode, 1);
}

作用:调用内部函数 __fopen_internal,参数 is32=1 表示处理 32 位偏移(大文件支持)。

(3) __fopen_internal 函数

_IO_FILE *
__fopen_internal(const char *filename, const char *mode, int is32) {// 实际调用 _IO_file_fopen(通过宏别名)if (INTUSE(_IO_file_fopen)((_IO_FILE *)new_f, filename, mode, is32)) {// 错误处理省略...}
}

关键点

  • INTUSE 宏用于兼容性处理,实际调用 _IO_new_file_fopen(通过别名 INTDEF2 定义)。

  • 参数 new_f 是未初始化的 _IO_FILE 结构体指针。

(4) _IO_new_file_fopen 函数

_IO_FILE *
_IO_new_file_fopen(_IO_FILE *fp, const char *filename, const char *mode, int is32not64) {// 解析模式字符串(如 "r"、"w+"),生成 posix_mode 和 flagsint omode = /* 解析 mode 字符串 */;int oflags = /* 转换为 open() 的 flags */;int oprot = /* 文件保护权限(如 0644) */;// 调用底层文件打开函数result = _IO_file_open(fp, filename, omode|oflags, oprot, read_write, is32not64);
}

作用

  • 解析用户传入的 mode 字符串(如 "rb"),转换为系统调用所需的标志(如 O_RDONLY)。

  • 调用 _IO_file_open 执行实际文件打开操作。

(5) _IO_file_open 函数

_IO_FILE *
_IO_file_open(_IO_FILE *fp, const char *filename, int posix_mode, int prot, int read_write, int is32not64) {// 调用系统级 open()fdesc = open(filename, posix_mode, prot);// 错误处理及 FILE 结构体初始化省略...
}

关键点

  • open 是宏定义,实际调用 __open(glibc 的封装)。

  • 返回的文件描述符 fdesc 会存储到 _IO_FILE 结构体中。

(6) __open 系统调用封装

#define open(Name, Flags, Prot) __open(Name, Flags, Prot)int __open(const char *file, int oflag, mode_t mode) {return INLINE_SYSCALL(open, 3, file, oflag, mode);
}

作用:通过宏和内联汇编触发系统调用。

(7) INLINE_SYSCALL 宏

#define INLINE_SYSCALL(name, nr, args...) \
({ \unsigned long int resultvar = INTERNAL_SYSCALL(name, , nr, args); \if (__builtin_expect(INTERNAL_SYSCALL_ERROR_P(resultvar), 0)) { \__set_errno(INTERNAL_SYSCALL_ERRNO(resultvar)); \resultvar = -1; \} \(long int)resultvar; \
})

功能

  • 调用 INTERNAL_SYSCALL 执行系统调用。

  • 检查返回值是否出错,若出错则设置 errno

(8) INTERNAL_SYSCALL 宏(x86-64 架构)

#define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \unsigned long int resultvar; \LOAD_ARGS_##nr(args) \  // 加载参数到寄存器asm volatile( \"syscall\n\t" \     // 触发系统调用指令: "=a"(resultvar) \ // 返回值存入 %rax: "0"(__NR_##name) ASM_ARGS_##nr \ // 系统调用号存入 %eax: "memory", "cc", "r11", "cx"); \  // 破坏的寄存器(long int)resultvar; \
})

关键点

  • 系统调用号通过 __NR_open 定义(例如 #define __NR_open 2)。

  • 使用 syscall 指令触发内核操作。


三、总结:fopen 的完整调用链

  • 用户调用fopen("file.txt", "r")

  • glibc 封装_IO_new_fopen → __fopen_internal → _IO_new_file_fopen → _IO_file_open

  • 系统调用open() → __open → INLINE_SYSCALL → syscall 指令。

  • 内核处理:内核根据系统调用号 __NR_open 执行文件打开操作,返回文件描述符。


四、关键细节说明

  • 兼容性处理INTDEF2 和 INTUSE 宏用于维护新旧符号的兼容性(如 _IO_file_fopen 和 _IO_new_file_fopen)。

  • 大文件支持:参数 is32 或 is32not64 控制是否使用 32 位偏移(影响 _IO_FILE 的内部实现)。

  • 错误处理:系统调用失败时,通过 __set_errno 设置错误码(如 ENOENT)。


五、伪代码简化

fopen()→ _IO_new_fopen()→ __fopen_internal()→ _IO_new_file_fopen()→ _IO_file_open()→ __open()→ INLINE_SYSCALL(open)→ syscall(__NR_open)  // 进入内核

通过以上分析,可以清晰看到 fopen 从用户接口到系统调用的完整路径,以及 glibc 在其中的封装和兼容性处理。

http://www.dtcms.com/a/533241.html

相关文章:

  • 国产数据库之XuguDB:虚怀若谷
  • 湖南移动官网网站建设微信营销的优缺点
  • 自建网站推广的最新发展河北网络建站
  • 精品课程网站建设意义最近免费韩国电影hd无
  • 怎么建设小说网站中国企业500强排行榜
  • 建设银行企业网站首页wordpress图像缩放插件
  • 奇偶分家:破解n^4+4^n的合数身份
  • js微任务输出
  • Linux小课堂: 守护进程与初始化进程服务详解
  • synchronized 和 Lock
  • 2.2.1.2 大数据方法论与实践指南-基于飞书项目的项目管理规范
  • 做防腐木网站优秀网站设计流程
  • LangChain最详细教程之Model I/O(二)Prompt Template
  • STM32F103C8T6_UART串口通信完整教程
  • Gorm(一)查询方法
  • 网站管理工具wordpress中文版和英文版区别
  • 新网网站空间到期停了 咋续费北海哪里做网站建设
  • 百日挑战-单词篇(第四天)
  • 6.1 操作系统的启动流程
  • 英语学习 第四天
  • Compose笔记(五十四)--Card
  • 西宁电商网站制作公司北京广告设计招聘
  • 阿里巴巴网站建设销售软件商店下载最新版
  • 交流耦合和直流耦合
  • 印刷厂网站建设方案利用网上菜谱做网站
  • Flutter 中, Flame + flame_forge2d世界坐标和屏幕坐标对齐
  • 石家庄建站网页模板siteservercms做的网站在后台进行修改教程
  • 基于单片机的楼道声光人体红外智能控制灯设计
  • 做热处理工艺的网站有哪些苏州优化外包
  • 给网站怎么做tag标签网站优化公司免费咨询