在 Ubuntu(Linux) 中,readdir 相关功能的实现分布在 C 库(glibc) 和 Linux 内核 两个层面。下面分层说明。
readdir 在 glibc 中的实现#include <dirent.h>
相关函数:
opendir()readdir()closedir()readdir_r()(已废弃)如果你下载了 glibc 源码:
glibc/sysdeps/posix/readdir.c
glibc/sysdeps/unix/sysv/linux/readdir.c
glibc/sysdeps/unix/sysv/linux/closedir.c
glibc/sysdeps/unix/sysv/linux/opendir.c
Ubuntu 上安装 glibc 源码:
apt source glibc
readdir() 实际上不是直接 syscall,而是:
readdir()
└─ getdents64() (系统调用)
glibc 会:
getdents64 读取多个 entrystruct dirent *getdents / getdents64 的实现int getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count);
int getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count);
fs/readdir.c
关键函数:
sys_getdents()sys_getdents64()iterate_dir()filldir() / filldir64()示例(简化):
SYSCALL_DEFINE3(getdents64, unsigned int, fd,
struct linux_dirent64 __user *, dirent,
unsigned int, count)
{
struct fd f = fdget(fd);
error = iterate_dir(f.file, &buf.ctx);
}
不同文件系统实现 ->iterate 接口:
fs/ext4/dir.c
fs/xfs/xfs_file.c
fs/btrfs/inode.c
例如 ext4:
const struct file_operations ext4_dir_operations = {
.iterate_shared = ext4_readdir,
};
用户程序
└─ readdir() [glibc]
└─ getdents64() [syscall]
└─ iterate_dir() [kernel fs/readdir.c]
└─ ext4_readdir() [具体文件系统]
查看系统调用:
strace ls
查看内核实现:
apt source linux
或在线:
如果你愿意,我可以:
你更想深入哪一层?