在 CentOS 上 readdir 失败,通常不是代码本身的问题,而是环境/权限/文件系统相关。下面按最常见原因 → 排查方法 → 解决办法给你一套思路。
readdir 失败一定要看 errno,不要只看返回值。
#include <errno.h>
#include <string.h>
perror("readdir");
// 或
printf("errno=%d: %s\n", errno, strerror(errno));
常见 errno 含义:
| errno | 含义 | 说明 |
|---|---|---|
| EACCES | 权限不足 | 目录没权限 |
| EBADF | 文件描述符无效 | opendir 没成功 |
| ENOENT | 目录不存在 | 路径错了 |
| ENOTDIR | 不是目录 | 当成目录打开 |
| EMFILE / ENFILE | 文件描述符耗尽 | 没关 dir |
| EIO | 磁盘/文件系统错误 | 硬盘或网络存储问题 |
ls -ld /path/to/dir
解决:
chmod +rx /path/to/dir
或切换用户:
sudo -u correct_user your_program
⚠️ 注意:父目录也要有 x 权限
错误示例:
DIR *dir = opendir("/some/path");
// 没判断 dir == NULL
readdir(dir); // 必崩或失败
正确写法:
DIR *dir = opendir(path);
if (!dir) {
perror("opendir");
return;
}
ls /path/to/dir
如果是符号链接:
ls -l /path/to/dir
解决:
stat() 判断CentOS 常见:
检查:
mount | grep nfs
df -h
dmesg | tail
解决:
mount -o remount /mnt/nfs
或加 soft,intr 挂载选项。
SELinux 会悄悄拒绝访问。
检查:
getenforce
临时验证:
setenforce 0
如果好了,说明是 SELinux:
ausearch -m avc -ts recent
解决:
semanage fcontext -a -t httpd_sys_content_t "/path/to/dir(/.*)?"
restorecon -Rv /path/to/dir
ulimit -n
lsof | wc -l
解决:
DIR*df -h
mount | grep "ro,"
dmesg | grep error
解决:
fsck /dev/sdX
mount -o remount,rw /
#include <dirent.h>
#include <stdio.h>
int main() {
DIR *dir = opendir("/tmp");
if (!dir) {
perror("opendir");
return 1;
}
struct dirent *entry;
while ((entry = readdir(dir))) {
printf("%s\n", entry->d_name);
}
if (errno) perror("readdir");
closedir(dir);
return 0;
}
你可以贴出:
我可以直接告诉你具体是哪一条原因 + 命令级解决办法。