readdir()32/64兼容性问题
我正试图让一些旧的遗留代码在新的64位系统上运行,而且我现在卡住了。 下面是一个小C文件,我用它来测试当前正在破坏的实际程序中存在的function。
#define _POSIX_SOURCE #include #include #undef _POSIX_SOURCE #include 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错误,当然没有打印出来。
我尝试使用readdir64()
代替readdir()
取得一些成功。 我不再得到errno EOVERFLOW,并且终端上出现了线条,但文件本身并没有被打印出来。 我假设这是由于缓冲区不是什么直接期望。
我试图使用dirent64
来尝试缓解这个问题,但每当我尝试这个时,我得到:
test.c:19:22 error: dereferencing pointer to incomplete type printf(" %s\n", dp->d_name);
我想知道是否有办法手动移动dp->d_name
缓冲区,以便与readdir()
一起使用。 我在dp->d_name
注意到使用readdir()
和dirent
导致dp->d_name
目录在dp->d_name[1]
列出,而readdir64()
和dirent
会在dp->d_name[8]
给出第一个目录。
那或者某种方式让dirent64
工作,或者我可能只是完全走错了路。
最后,值得注意的是程序在没有包含-m32
标志的情况下完美运行,所以我假设它必须是某个地方的32/64兼容性错误。 任何帮助表示赞赏。
感谢@Martin在上面的评论中,我被引导尝试在我的代码中定义dirent64结构。 这很有效。 可能有一个#define可以用来绕过将libc .h代码粘贴到我自己的代码中,但是现在这个有用。
我需要的代码可以在
我想我还应该注意,这使得它使用readdir64()和dirent64
为了获得带有GCC和Glibc的64位ino_t
,您需要定义_XOPEN_SOURCE
和_FILE_OFFSET_BITS=64
。
$ echo '#include ' | 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的文件系统进行测试,因此我不保证您不会遇到其他问题。