【问题标题】:readdir() 32/64 compatibility issuesreaddir() 32/64 兼容性问题
【发布时间】:2015-02-17 16:44:25
【问题描述】:

我正在尝试让一些旧的遗留代码在新的 64 位系统上运行,但我目前陷入困境。下面是一个小 C 文件,我用来测试当前正在中断的实际程序中存在的功能。

#define _POSIX_SOURCE
#include <dirent.h>
#include <sys/types.h>
#undef _POSIX_SOURCE
#include <stdio.h>

main(){
    DIR *dirp;
    struct dirent *dp;
    char *const_dir;

    const_dir = "/any/path/goes/here";

    if(!(dirp = opendir(const_dir)))
        perror("opendir() error");
    else{
        puts("contents of path:");
        while(dp = readdir(dirp))
            printf(" %s\n", dp->d_name);
        closedir(dirp);
    }
}

问题:

操作系统是 Red Hat 7.0 Maipo x86_64。 旧代码是 32 位的,必须保持这种状态。

我已经使用带有g++-m32 标志编译了该程序的正常工作。出现的问题是在运行时,readdir() 获得一个 64 位 inode,然后抛出一个 EOVERFLOW errno,当然没有打印出来。

我尝试使用readdir64() 代替readdir() 取得了一些成功。我不再得到 errno EOVERFLOW,并且这些行出现在终端上,但文件本身没有被打印。我假设这是由于缓冲区不是dirent 所期望的。

我尝试使用dirent64 来缓解这个问题,但每当我尝试这样做时,我都会得到:

test.c:19:22 error: dereferencing pointer to incomplete type 
  printf(" %s\n", dp->d_name);

我想知道是否有办法手动移动 dp-&gt;d_name 缓冲区以供 direntreaddir() 一起使用。我在 Gdb 中注意到,使用 readdir()dirent 会导致 dp-&gt;d_name 的目录位于 dp-&gt;d_name[1],而 readdir64()dirent 给出的第一个目录位于 dp-&gt;d_name[8]

或者以某种方式让dirent64 工作,或者我完全走错了路。

最后,值得注意的是,该程序在不包含 -m32 标志的情况下运行良好,所以我假设它必须是某个地方的 32/64 兼容性错误。任何帮助表示赞赏。

【问题讨论】:

  • 为什么不简单定义缺失的类型并使用dirent64?
  • 您的意思是定义 dirent64 的方式与仅在我的程序中在 dirent.h 中定义的方式相同?
  • 那...实际上在将结构从 bits/dirent.h 中拉出并手动将其放入我的代码中后效果很好。我敢肯定在某个地方有一个定义可以用来代替,但这目前有效。谢谢!
  • 很高兴我能帮上忙。 :)

标签: c file 32-bit dirent.h


【解决方案1】:

感谢上面 cmets 中的 @Martin,我被引导尝试在我的代码中定义 dirent64 结构。这行得通。可能有一个#define 可以用来规避将 libc .h 代码粘贴到我自己的代码中,但目前这可行。

我需要的代码在&lt;bits/dirent.h>

我想我还应该注意,这使得它可以同时使用 readdir64() 和 dirent64

【讨论】:

  • 为什么不在程序中包含&lt;bits/dirent.h&gt;
  • dirent.h 中的代码在某个#define 下,因此预处理器将其丢弃。为了启用dirent.h 中的64 位代码,必须定义一些编译标志。页面here 建议_FILE_OFFSET_BITS=64
  • 是的,我尝试使用在 .h 文件中找到的一堆#define,但我从来没有用它来获取 dirent64。不幸的是,我不能包含&lt;bits/dirent.h&gt;,如果你打开它指定不直接包含它的头文件,而是包含&lt;dirent.h&gt; 并使用#defines 来访问它的功能:(
【解决方案2】:

为了使用 GCC 和 Glibc 获得 64 位 ino_t,您需要定义 features _XOPEN_SOURCE_FILE_OFFSET_BITS=64

$ echo '#include <dirent.h>' | gcc -m32 -E -D_XOPEN_SOURCE -D_FILE_OFFSET_BITS=64 - | grep ino
__extension__ typedef unsigned long int __ino_t;
__extension__ typedef __u_quad_t __ino64_t;
typedef __ino64_t ino_t;
    __ino64_t d_ino;

我是根据阅读和检查预处理器的文档说的,而不是根据丰富的经验或使用 inode 编号高于 2^32 的文件系统进行测试,所以我不保证您不会遇到其他问题。

【讨论】:

    猜你喜欢
    • 2019-08-19
    • 2010-10-21
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多