dirent.h中readdir()函数的迭代逻辑究竟在哪里?
寻找readdir的迭代逻辑位置
你找到的glibc中__readdir只是一个弱符号的默认占位实现,仅在没有对应平台的具体实现时生效——实际运行时调用的是Linux平台专属的readdir版本,迭代逻辑就藏在这里。
1. 实际实现的位置
Linux平台下,glibc的readdir具体实现位于sysdeps/unix/sysv/linux/目录下(不同CPU架构可能在子目录里,比如sysdeps/unix/sysv/linux/x86_64/readdir.c),而非你查看的dirent/readdir.c。
2. 迭代逻辑的核心
readdir的迭代依赖两个关键部分:
DIR结构体的状态维护:这个结构体内部保存了目录流的当前位置、缓存目录条目的缓冲区、缓冲区中剩余未返回的条目数等状态信息。getdents系统调用:当缓冲区里没有未返回的条目时,readdir会调用getdents从内核读取一批目录条目到缓冲区,之后从缓冲区逐个返回条目,同时更新DIR结构体里的内部指针(这就是你要找的类似something++的迭代步骤)。
每次调用readdir(dp)时,函数会自动执行以下逻辑:
- 若缓冲区还有未返回的条目,直接返回下一个,并移动内部指针;
- 若缓冲区为空,向内核请求新的一批条目填充缓冲区,再返回第一个条目;
- 当目录所有条目读取完毕或出错时,返回NULL,循环终止。
3. 关于废弃的readdir系统调用
早期Linux确实存在readdir系统调用,但它早已被getdents取代,现在glibc的readdir完全基于getdents实现——你在内核源码中搜索到的readdir相关内容,大多是这个旧系统调用的遗留代码。
4. 其他疑问的补充
- 你提到的LD_PRELOAD是动态库劫持的手段,和readdir的原生实现无关;
- 直接全局搜索glibc源码中的readdir会因为跨平台的多版本实现导致结果冗余,定位到Linux专属目录就能找到目标代码;
- man手册中提到的读取顺序由文件系统决定,本质是因为
getdents获取的是文件系统自身维护的目录条目顺序。
内容的提问来源于stack exchange,提问作者Timur Timak
相关产品推荐
相关产品推荐

