在 CentOS 上调用 readdir() 失败,通常不是“CentOS 特有”的问题,而是权限、路径、文件描述符或编程用法导致的。下面按最常见原因 → 排查方法 → 示例来梳理。
readdir() 只能用于 DIR*,如果 opendir() 返回 NULL,后续 readdir() 必然失败。
DIR *dir = opendir("/some/path");
if (!dir) {
perror("opendir");
return -1;
}
✅ 检查:
ls -ld /some/path
在 CentOS 中:
例如:
drwxr-x--- root root /data
普通用户调用 readdir() 会失败。
✅ 解决:
chmod +rx /data
或切换用户 / sudo
CentOS 默认开启 SELinux,这是非常常见但容易被忽略的原因。
即使权限正确,readdir() 仍可能失败。
✅ 查看是否 SELinux 拦截:
dmesg | grep avc
ausearch -m avc -ts recent
✅ 临时验证:
setenforce 0
如果此时成功 → 就是 SELinux 问题。
✅ 解决方式:
chcon -R -t var_t /your/dir
如果:
opendir() 成功readdir() 可能返回 NULL 且 errno = ENOENT
readdir() 返回 NULL 不一定是错误:
NULL 且 errno == 0 → 目录读完NULL 且 errno != 0 → 真正失败✅ 正确写法:
errno = 0;
struct dirent *entry = readdir(dir);
if (!entry) {
if (errno != 0) {
perror("readdir");
}
}
如果你用的是:
readdir()
在多线程中不安全的。
✅ 应使用:
readdir_r()
或现代 glibc 中 readdir() 已线程安全(但需确认)
如:
✅ 检查:
mount | grep your_path
dmesg | tail
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
int main() {
DIR *dir = opendir("/tmp");
if (!dir) {
perror("opendir");
return 1;
}
errno = 0;
struct dirent *de;
while ((de = readdir(dir)) != NULL) {
printf("%s\n", de->d_name);
}
if (errno != 0)
perror("readdir");
closedir(dir);
return 0;
}
opendir() 是否成功r/x 权限errno 是否非 0如果你愿意,可以把:
errno)发出来,我可以精准定位是哪一条原因。