温馨提示×

centos readdir出错原因

小樊
34
2026-10-17 19:03:41
栏目: 智能运维

在 CentOS(以及 Linux 一般环境)里,readdir() 出错通常有系统调用层面和编程/权限层面两类原因。下面按常见情况给你梳理一下。


一、readdir() 返回 NULL 但 errno 不为 0(真正“出错”)

readdir() 本身在正常读到目录末尾时也会返回 NULL,此时 errno 不变(通常是 0)。
只有 返回 NULL 且 errno ≠ 0 才是真正错误。

常见 errno 及原因

errno 含义 在 CentOS 上常见原因
EBADF 文件描述符无效 DIR* 已关闭或被破坏
ENOENT 目录不存在 目录被删除或路径错误
EACCES / EPERM 权限不足 用户无目录读/执行权限
ENOTDIR 不是目录 用 opendir() 打开了一个普通文件
EMFILE / ENFILE 文件描述符耗尽 进程或系统打开文件过多
ENOMEM 内存不足 系统资源紧张
EFAULT 参数地址非法 指针为空或已释放

二、CentOS 特有或常见人为原因

1. 权限问题(最常见)

ls -ld /path/dir
  • 需要 r + x 权限才能 readdir
  • 即使有 r,没有 x 也会失败

2. SELinux 限制

CentOS 默认开启 SELinux:

getenforce
  • Enforcing 模式下,服务(如 httpd、nginx)可能被禁止读目录
  • 查看拒绝日志:
ausearch -m avc -ts recent

3. 目录在 NFS / 网络挂载上

  • NFS 超时、权限映射错误
  • readdir() 可能返回 EIO 或 ESTALE

4. 目录被并发删除或重命名

  • 多线程 / 多进程场景下
  • opendir() 后目录被 rm -rf

5. 大量小文件导致性能/资源问题

  • readdir() 很慢
  • 可能触发 EMFILE

三、编程层面常见错误

错误示例 1:未检查 opendir 返回值

DIR *dir = opendir(path);
readdir(dir); // dir 可能为 NULL

错误示例 2:目录流被提前 closedir

closedir(dir);
readdir(dir); // 未定义行为

错误示例 3:多线程共用 DIR*

  • readdir() 不是线程安全
  • 应使用 readdir_r()(已废弃)或加锁

四、调试建议(CentOS)

# 查看错误
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;
}

如果你能贴出:

  • 错误代码 / errno
  • CentOS 版本
  • 是 C / C++ / Python / Shell
  • 目录类型(本地 / NFS / Docker)

我可以更精确地帮你定位原因。

0 踩