在 Ubuntu(Linux)里用 opendir() 打开目录时,如果没有权限或路径不对,会返回 NULL,并且 errno 会说明原因。下面从「原理 → 常见错误 → 处理方法 → 示例」讲清楚。
opendir() 与权限的关系#include <dirent.h>
DIR *opendir(const char *name);
返回 DIR *
返回 NULL,并设置 errno
常见权限相关错误:
| errno | 含义 |
|---|---|
EACCES |
权限不足(最常见) |
ENOENT |
目录不存在 |
ENOTDIR |
不是目录 |
EMFILE / ENFILE |
文件描述符耗尽 |
opendir() 会没权限?ls -ld /some/dir
需要 执行权限(x) 才能 opendir:
drwxr-x--- user group dir
如果你是其他用户,就会 EACCES
即使目录权限是 777,父目录没 x 也不行:
/home/secret (no x for others)
/home/secret/logs
例如:
opendir("/root");
普通用户必然失败
某些服务受限制(如 nginx、docker)
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
DIR *dir = opendir("/path/to/dir");
if (dir == NULL) {
perror("opendir");
// 或
fprintf(stderr, "opendir failed: %s\n", strerror(errno));
return -1;
}
chmod +x /path/to/dir
chmod 755 /path/to/dir
父目录也必须可执行:
chmod +x /parent
sudo chown youruser:yourgroup /path/to/dir
或运行程序时切换用户:
sudo -u alloweduser ./yourapp
access() 先判断(可选)#include <unistd.h>
if (access("/path/to/dir", R_OK | X_OK) != 0) {
perror("access");
}
⚠️ 注意:access() 有 TOCTOU 风险,仅用于提示
sudo ./yourapp
只适合系统工具
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
int main() {
const char *path = "/var/log";
DIR *dir = opendir(path);
if (!dir) {
perror("opendir");
return 1;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;
}
namei -l /path/to/dir
可以一眼看出哪一层权限不足。
如果你愿意,可以贴出:
ls -ld 输出我可以帮你精确判断是哪一种权限问题。