在 Debian(以及其它 Linux 系统)里,readdir 本身只负责读取目录项,而是否能成功读取,取决于进程对该目录的权限。下面从原理到常见问题给你梳理一下。
readdir 是在 已经成功 opendir() 的目录流 上工作的:
DIR *dir = opendir("/some/dir");
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
// 读取目录项
}
r(读)权限
opendir() 会失败,errno = EACCESx(执行)权限
x 权限,即使有 r 也不能 opendir()⚠️ readdir 不会检查文件本身的权限,只检查目录权限。
| 情况 | 现象 | errno |
|---|---|---|
| 目录无读权限 | opendir 返回 NULL |
EACCES |
| 目录无执行权限 | opendir 返回 NULL |
EACCES |
| 目录不存在 | opendir 返回 NULL |
ENOENT |
| 不是目录 | opendir 返回 NULL |
ENOTDIR |
示例:
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
DIR *dir = opendir(path);
if (!dir) {
perror("opendir");
}
if (access(path, R_OK | X_OK) != 0) {
fprintf(stderr, "无权限访问目录: %s\n", path);
return;
}
sudoif (opendir(path) == NULL) {
if (errno == EACCES) {
// 跳过
continue;
}
}
readdir 只返回:
它不会告诉你子文件是否可读,例如:
entry->d_name; // 文件名
要访问文件内容,需要单独检查:
if (access(full_path, R_OK) != 0) {
// 无权限
}
. 开头readdir 会返回,需自行过滤readdir 不解析lstat 判断readdir 可能成功但内容异常Debian 下
readdir的权限处理,本质上是“目录是否有 r+x 权限”,而不是文件权限;遇到EACCES,应在opendir阶段处理,而不是readdir阶段。
如果你有具体代码或场景(比如递归遍历、FTP、Web 服务、setuid 程序),我可以帮你针对性分析。