在 CentOS(以及一般 Linux)上,用 readdir() 读取目录时,权限问题主要体现在“能不能打开目录”和“能不能读到条目”两方面。下面按实际场景说明如何处理。
readdir() 本身不检查文件权限,它只读取已经打开的目录流:
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);
权限检查发生在:
没有
x:打不开目录
没有r:能打开,但 readdir 可能失败或返回空
DIR *dir = opendir("/root");
if (!dir) {
perror("opendir");
}
可能错误:
EACCES:权限不足ENOENT:目录不存在✅ 处理方式:
if (dir == NULL) {
if (errno == EACCES) {
fprintf(stderr, "权限不足,无法访问目录\n");
}
return -1;
}
CentOS 默认:
dr-xr-x---. root root /root
普通用户无权限 → opendir 失败
✅ 解决方式:
sudo 运行程序/root)readdir 只列目录项,不关心文件本身权限
但后续 stat/open 文件可能失败
✅ 建议:
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
struct stat st;
if (stat(entry->d_name, &st) == -1) {
if (errno == EACCES)
continue; // 跳过无权限文件
}
}
在 opendir 前:
#include <unistd.h>
if (access(path, R_OK | X_OK) != 0) {
perror("access");
return -1;
}
⚠ 注意:access 有 TOCTOU 风险,仅做预判
如果你是写系统工具:
setuid(uid);
setgid(gid);
opendir(path);
CentOS 上注意:
setsebool 或写 policy有时 ls 可以,readdir 不行:
getenforce
✅ 排查:
ausearch -m avc -ts recent
✅ 临时测试:
setenforce 0
(生产环境不推荐长期关闭)
755644DIR *dir = opendir(path);
if (!dir) {
perror("opendir");
return -1;
}
struct dirent *de;
while ((de = readdir(dir))) {
if (de->d_name[0] == '.') continue;
printf("%s\n", de->d_name);
}
closedir(dir);
如果你有:
可以贴出来,我可以直接帮你改。