在 Debian(以及其它 Linux 发行版)里,readdir() 本身不会单独判断权限,它依赖的是目录的访问权限 + open() 打开目录的权限。权限问题通常出现在调用 opendir() / fdopendir() 这一步,而不是 readdir() 本身。
下面按“原理 → 常见错误 → 处理方法 → 示例”来说明。
DIR *dir = opendir("/some/path");
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
...
}
关键点:
opendir() 需要目录的执行权限(x)readdir() 需要目录的读权限(r)opendir() 返回 NULLerrno == EACCESopendir: Permission denied
原因:
r 或 xx 权限(无法进入)解决:
ls -ld /path
namei -l /path
stat(entry->d_name, &st); // 失败
原因:
readdir() 只列名字,不检查文件权限处理:
access() 判断#include <dirent.h>
#include <errno.h>
#include <stdio.h>
DIR *dir = opendir(path);
if (!dir) {
if (errno == EACCES) {
perror("无权限访问目录");
} else {
perror("opendir");
}
return;
}
DIR *sub = opendir(fullpath);
if (!sub) {
if (errno == EACCES)
continue; // 跳过无权限目录
perror("opendir");
continue;
}
int fd = open(path, O_RDONLY | O_DIRECTORY);
if (fd < 0) {
perror("open");
return;
}
DIR *dir = fdopendir(fd);
优点:
fstat()O_NOFOLLOW 防符号链接即使文件权限正确,也可能被限制:
dmesg | grep apparmor
aa-status
mount | grep noexec
某些目录(如 /proc, /sys)权限表现特殊。
namei -l /var/www/private
ls -ld /var /var/www /var/www/private
sudo -u www-data bash -c 'ls /var/www/private'
✅ readdir() 本身不报权限错误
✅ 权限问题来自 opendir()
✅ 一定要检查 errno == EACCES
✅ 递归遍历时要容错跳过无权限目录
如果你有具体代码或目录结构,我可以帮你精确定位是哪一级权限出问题。