readdir() 32/64 兼容性问题 [英] readdir() 32/64 compatibility issues

查看:32
本文介绍了readdir() 32/64 兼容性问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to get some old legacy code working on new 64-bit systems, and I'm currently stuck. Below is a small C file I'm using to test functionality that exists in the actual program that is currently breaking.

#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
", dp->d_name);
        closedir(dirp);
    }
}

问题:

操作系统是 Red Hat 7.0 Maipo x86_64.遗留代码是 32 位的,必须保持这种方式.

The OS is Red Hat 7.0 Maipo x86_64. The legacy code is 32-bit, and must be kept that way.

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

I've gotten the compile for the program working fine using the -m32 flag with g++. The problem that arises is during runtime, readdir() gets a 64-bit inode and then throws an EOVERFLOW errno and of course nothing gets printed out.

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

I've tried using readdir64() in place of readdir() to some success. I no longer get the errno EOVERFLOW, and the lines come out on the terminal, but the files themselves don't get printed. I'm assuming this is due to the buffer not being what dirent expects.

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

I've attempted to use dirent64 to try to alleviate this problem but whenever I attempt this I get:

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

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

I'm wondering if there's a way to manually shift the dp->d_name buffer for dirent to be used with readdir(). I've noticed in Gdb that using readdir() and dirent results in dp->d_name having directories listed at dp->d_name[1], whereas readdir64() and dirent gives the first directory at dp->d_name[8].

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

That or somehow get dirent64 to work, or maybe I'm just on the wrong path completely.

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

Lastly, it's worth noting that the program functions perfectly without the -m32 flag included, so I'm assuming it has to be a 32/64 compatibility error somewhere. Any help is appreciated.

推荐答案

为了得到一个带有 GCC 和 Glibc 的 64 位 ino_t,你需要定义 特性 _XOPEN_SOURCE_FILE_OFFSET_BITS=64.

In order to get a 64-bit ino_t with GCC and Glibc, you need to define the features _XOPEN_SOURCE and _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 的文件系统进行测试,所以我不保证你不会遇到其他问题.

I say this from documentation reading and checking the preprocessor, not from deep experience or testing with a filesystem with inode numbers above 2^32, so I don't guarantee that you won't run into other problems down the line.

这篇关于readdir() 32/64 兼容性问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆