在 CentOS(实际上任何 Linux 发行版)上,readdir() 读取目录失败,通常不是“CentOS 特有”的问题,而是系统调用/环境/权限/文件系统层面的原因。下面按常见原因 → 现象 → 排查方法给你系统梳理一下。
readdir() 本身 returned NULL 的两种情况在 C 中:
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
...
}
readdir() 返回 NULL 不代表一定出错,需要区分:
errno == 0✅ 不是失败
readdir() 返回 NULLerrno != 0常见 errno:
EBADF:目录流无效ENOENT:目录在遍历中被删除EACCES:权限不足ENOMEM:内存不足EOVERFLOW:某些字段溢出(少见)readdir 失败的常见原因ls -ld /path/to/dir
可能情况:
x(执行)权限x 权限示例错误:
Permission denied
✅ 解决:
chmod +x /path
chmod +x /parent/path
opendir() 后、遍历中被 rm -rf现象:
readdir() 失败ENOENT✅ 解决:
openat() + 文件描述符方式CentOS 默认开启 SELinux。
即使:
ls -l # 看起来有权限
SELinux 也可能禁止访问。
排查:
getenforce
ausearch -m avc -ts recent
常见错误:
avc: denied { read } for ...
✅ 解决:
setenforce 0
CentOS 常用于服务器,挂载目录很常见。
失败原因:
ro 但代码假设可写readdir 的 FUSE排查:
mount | grep path
dmesg | tail
现象:
readdir() 极慢排查:
df -i
fsck(卸载后)
_FILE_OFFSET_BITS=64 未定义readdir 返回 EOVERFLOW✅ 解决:
#define _FILE_OFFSET_BITS 64
错误示例:
closedir(dir);
readdir(dir); // ❌
结果:
EBADFreaddir 失败的正确姿势#include <dirent.h>
#include <errno.h>
#include <stdio.h>
DIR *dir = opendir(path);
if (!dir) {
perror("opendir");
return;
}
struct dirent *e;
errno = 0;
while ((e = readdir(dir)) != NULL) {
printf("%s\n", e->d_name);
}
if (errno != 0) {
perror("readdir");
}
closedir(dir);
ls -ld /path
getenforce
mount | grep path
df -i
dmesg | tail
strace ./your_program
你可以直接贴:
我可以帮你精确定位是哪一类问题。