readdir()32/64兼容性问题

时间:2014-12-18 19:35:15

标签: c file 32-bit dirent.h

我正在尝试在新的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位,必须保持这种状态。

我使用-m32标记g++使程序编译工作正常。出现的问题是在运行时,readdir()得到一个64位的inode,然后抛出一个EOVERFLOW错误,当然没有打印出来。

我尝试使用readdir64()代替readdir()取得一些成功。我不再获得errno EOVERFLOW,并且终端上出现了线条,但文件本身不会被打印出来。我假设这是因为缓冲区不是dirent所期望的。

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

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

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

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

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

2 个答案:

答案 0 :(得分:1)

感谢@Martin在上面的评论中,我被引导尝试在我的代码中定义dirent64结构。这有效。可能有一个#define可以用来绕过将libc .h代码粘贴到我自己的代码中,但现在可以使用了。

我需要的代码可以在<bits/dirent.h&gt;

中找到

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

答案 1 :(得分:1)

为了获得带有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的文件系统进行测试,因此我不保证您不会遇到其他问题。