0

我正在使用 opendir / readdir / closedir 来重现类似于 ls 的程序,它运行得非常好,直到我尝试使用 ls "/dev/" 当涉及到带有递归选项的 "/dev/fd/" 时,它找到了更多比实际存在的文件,那些不是隐藏文件(我的意思是“。”开始文件)。真正的 ls 给我:"/dev/fd/ :" "0 1 2 3" 我的也是。但是,问题是在 gdb 中,它又找到了 3 个文件,分别是 4,5 和 6。我听说 gdb 创建了自己的环境,所以让我们忘记这一点。当我尝试 ls "/dev/fd/" -R 时,真正的 ls 会立即停止列表,而我的程序给出:

“/dev/fd/3:”

“/dev/fd/3/3/”

“/dev/fd/3/3/......../10”

stat 至少在 40 个文件后返回 -1,但执行继续:分段错误。

在我的计算机中,“/dev/fd/3/”和符号链接也是如此,宏“S_ISDIR”在现有文件上返回 0,但在不存在的文件上返回 0,例如:“/dev/fd/6/”它返回1...

我想知道为什么我的程序出错而真正的 ls 没有,我注意到 ls 在我的计算机中使用 stat64,但是当我这样做时仍然出错.. 它还使用 fstat64、futex 和其他我不使用的系统调用知道。

我可以向您展示一些我的代码示例或更多细节,这真的很难为我解释,我很抱歉。

谢谢。

PS:我在 readdir 联机帮助页中没有得到该语句:“readdir 返回的数据可能会被后续对同一目录流的 readdir 调用覆盖”

4

1 回答 1

1

PS:我在 readdir 联机帮助页中没有得到该语句:“readdir 返回的数据可能会被后续对同一目录流的 readdir 调用覆盖”

他们基本上说的是该函数不可重入,并且返回的指针readdir不应简单地缓存为唯一值,因为指向的基础数据将在您下次调用该readdir函数时发生变化. 基本上,它们允许实现定义可以由函数回收的静态分配的数据,或者由操作系统管理的动态内存,这样调用者readdir就不必担心管理返回值指向的内存readdir。例如,对于如下示例函数:

int* my_sample_increment()
{
    static int val = 0;
    val++;

    return &val;
}

如果你要做类似的事情

int* int_ptr_1 = my_sample_increment();
int* int_ptr_2 = my_sample_increment();

然后两者int_ptr_1int_ptr_2将指向相同的值,在这种情况下它将是 value 1。每个指针都不会指向唯一的整数值。

所以同样如此readdir。您不能简单地调用和存储返回的指针,期望在以后使用它,而不会在保存指针的时间和使用它的时间之间的readdir任何后续调用中修改指向的数据。readdir如果您需要这样的功能,这就是可重入版本readdir_r的用途。

于 2011-08-03T04:27:12.990 回答