在 Ubuntu(Linux)里,copendir 并不是标准 API,POSIX 只定义了:
opendirreaddirclosedirrewinddir如果你看到 copendir,通常是 某些项目或教材里的自定义函数,用于“复制一个已经打开的目录流(DIR*)”。
下面分几种情况说明 在 Ubuntu 下如何实现类似 copendir 的功能。
copendirDIR * 是一个 不透明结构体,标准并没有规定它的内部实现,因此:
所以 POSIX 没有 copendir,只能自己实现。
用
dirfd()获取目录 fd,然后openat()+fdopendir()
这是 最干净、最安全、最推荐 的方式。
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
DIR *copendir(DIR *dirp) {
if (!dirp)
return NULL;
int fd = dirfd(dirp);
if (fd < 0)
return NULL;
int new_fd = openat(fd, ".", O_RDONLY | O_DIRECTORY);
if (new_fd < 0)
return NULL;
return fdopendir(new_fd);
}
DIR *dir1 = opendir("/tmp");
DIR *dir2 = copendir(dir1);
struct dirent *ent;
while ((ent = readdir(dir2)) != NULL) {
printf("%s\n", ent->d_name);
}
closedir(dir1);
closedir(dir2);
✅ 优点:
opendir 原路径DIR *copendir(DIR *dirp) {
char path[1024];
snprintf(path, sizeof(path), "/proc/self/fd/%d", dirfd(dirp));
return opendir(path);
}
⚠️ 缺点:
/proc其实 不需要 copendir,直接用:
rewinddir(dirp);
或者:
seekdir(dirp, 0);
✅ 适用于:
| 需求 | 推荐方案 |
|---|---|
| 复制 DIR* | dirfd + openat + fdopendir |
| 重新遍历 | rewinddir |
| 多线程 | 复制 DIR* |
| 跨平台 | 复制 DIR* |
如果你愿意,可以告诉我:
copendir我可以帮你写一个 完整可编译的 demo 或 适配你项目的版本。