我的代码是这样的:
DIR* pDir = opendir("/path/to/my/dir");
struct dirent pFile = NULL;
while ((pFile = readdir())) {
// Check if it is a .zip file
if (subrstr(pFile->d_name,".zip") {
// It is a .zip file, delete it, and the matching log file
char zipname[200];
snprintf(zipname, sizeof(zipname), "/path/to/my/dir/%s", pFile->d_name);
unlink(zipname);
char* logname = subsstr(zipname, 0, strlen(pFile->d_name)-4); // Strip of .zip
logname = appendstring(&logname, ".log"); // Append .log
unlink(logname);
}
closedir(pDir);
Run Code Online (Sandbox Code Playgroud)
(此代码未经测试,纯粹是一个例子)
关键是:是否允许在使用readdir()循环目录时删除目录中的文件?或者readdir()仍然会找到已删除的.log文件?
从POSIX readdir引用:
如果在最近一次调用opendir()或rewinddir()之后从目录中删除或添加了文件,则是否指定后续调用readdir()是否返回该文件的条目.
所以,我猜是......这取决于.
这取决于操作系统,在一天中的时间,添加/删除文件的相对顺序,...
而且,作为另一点,在readdir()函数返回和尝试unlink()文件之间,某些其他进程可能已删除该文件而您unlink()失败.
编辑
我测试了这个程序:
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
int main(void) {
struct dirent *de;
DIR *dd;
/* create files `one.zip` and `one.log` before entering the readdir() loop */
printf("creating `one.log` and `one.zip`\n");
system("touch one.log"); /* assume it worked */
system("touch one.zip"); /* assume it worked */
dd = opendir("."); /* assume it worked */
while ((de = readdir(dd)) != NULL) {
printf("found %s\n", de->d_name);
if (strstr(de->d_name, ".zip")) {
char logname[1200];
size_t i;
if (*de->d_name == 'o') {
/* create `two.zip` and `two.log` when the program finds `one.zip` */
printf("creating `two.zip` and `two.log`\n");
system("touch two.zip"); /* assume it worked */
system("touch two.log"); /* assume it worked */
}
printf("unlinking %s\n", de->d_name);
if (unlink(de->d_name)) perror("unlink");
strcpy(logname, de->d_name);
i = strlen(logname);
logname[i-3] = 'l';
logname[i-2] = 'o';
logname[i-1] = 'g';
printf("unlinking %s\n", logname);
if (unlink(logname)) perror("unlink");
}
}
closedir(dd); /* assume it worked */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在我的计算机上,readdir()找到已删除的文件,但找不到opendir()和之间创建的文件readdir().但在另一台计算机上可能会有所不同; 如果我使用不同的选项编译,我的计算机可能会有所不同; 如果我升级内核可能会有所不同; ...
我正在测试我的新 Linux 参考书。Michael Kerrisk 的《Linux 编程接口》内容如下:
SUSv3 明确指出,未指定 readdir() 是否会返回自上次调用 opendir() 或 rewinddir() 以来添加或删除的文件名。保证返回自上次此类调用以来既未添加也未删除的所有文件名。
我认为未指定的是尚未扫描的 dirents 会发生什么。一旦条目被返回,无论您是否取消当前目录的链接,都可以 100% 保证它不会再被返回。
另请注意第二句提供的保证。由于您无需理会其他文件,而仅取消 zip 文件的当前条目的链接,因此 SUSv3 保证将返回所有其他文件。日志文件会发生什么是未定义的。它可能会或可能不会被 readdir() 返回,但就您而言,它应该不会有害。
我探索这个问题的原因是为了找到一种有效的方法来在 exec() 之前关闭子进程中的文件描述符。
Stevens 在 APUE 中建议的方法是执行以下操作:
int max_open = sysconf(_SC_OPEN_MAX);
for (int i = 0; i < max_open; ++i)
close(i);
Run Code Online (Sandbox Code Playgroud)
但我正在考虑使用类似于 OP 中找到的代码来扫描 /dev/fd/ 目录,以确切地知道我需要关闭哪些 fd。(我自己特别注意,跳过 DIR 句柄中包含的 dirfd。)
| 归档时间: |
|
| 查看次数: |
7472 次 |
| 最近记录: |