在 CentOS(以及 Linux 一般环境)里,readdir() 出错通常有系统调用层面和编程/权限层面两类原因。下面按常见情况给你梳理一下。
readdir() 本身在正常读到目录末尾时也会返回 NULL,此时 errno 不变(通常是 0)。
只有 返回 NULL 且 errno ≠ 0 才是真正错误。
| errno | 含义 | 在 CentOS 上常见原因 |
|---|---|---|
EBADF |
文件描述符无效 | DIR* 已关闭或被破坏 |
ENOENT |
目录不存在 | 目录被删除或路径错误 |
EACCES / EPERM |
权限不足 | 用户无目录读/执行权限 |
ENOTDIR |
不是目录 | 用 opendir() 打开了一个普通文件 |
EMFILE / ENFILE |
文件描述符耗尽 | 进程或系统打开文件过多 |
ENOMEM |
内存不足 | 系统资源紧张 |
EFAULT |
参数地址非法 | 指针为空或已释放 |
ls -ld /path/dir
readdirr,没有 x 也会失败CentOS 默认开启 SELinux:
getenforce
Enforcing 模式下,服务(如 httpd、nginx)可能被禁止读目录ausearch -m avc -ts recent
readdir() 可能返回 EIO 或 ESTALEopendir() 后目录被 rm -rfreaddir() 很慢EMFILEDIR *dir = opendir(path);
readdir(dir); // dir 可能为 NULL
closedir(dir);
readdir(dir); // 未定义行为
readdir() 不是线程安全readdir_r()(已废弃)或加锁# 查看错误
perror("readdir");
# 跟踪系统调用
strace -e trace=open,openat,getdents,readdir ./your_program
# 检查权限
namei -l /path/to/dir
# 检查 SELinux
getenforce
ausearch -m avc
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
int main() {
DIR *dir = opendir("/tmp");
if (!dir) {
perror("opendir");
return 1;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
if (errno != 0) {
perror("readdir");
}
closedir(dir);
return 0;
}
如果你能贴出:
我可以更精确地帮你定位原因。