温馨提示×

linux readdir怎么兼容32位

小樊
54
2026-10-17 07:40:30
栏目: 智能运维

在 Linux 下使用 readdir 兼容 32 位程序,核心问题在于不是函数本身不兼容,而是程序编译环境、ABI 和文件偏移类型(off_t / ino_t)是否一致。下面分情况说清楚。


一、readdir 本身是否区分 32 / 64 位?

✅ readdir 是 POSIX 接口,不区分 32/64 位

struct dirent *readdir(DIR *dirp);

真正区分的是:

  • readdir vs readdir64
  • struct dirent vs struct dirent64
  • off_t 是 32 位还是 64 位(_FILE_OFFSET_BITS)

二、32 位程序最常见的问题

1️⃣ ino_t / off_t 是 32 位(legacy)

在 32 位系统或未开启大文件支持时:

struct dirent {
    ino_t d_ino;     // 32 位
    off_t d_off;     // 32 位
    ...
};

如果目录中 inode > 2^32 或使用了 64 位文件系统,会导致:

  • readdir 返回 NULL
  • errno = EOVERFLOW

✅ 解决方法(推荐)

#define _FILE_OFFSET_BITS 64
#include <dirent.h>

或者直接用:

readdir64()
struct dirent64

三、32 位和 64 位混编时的兼容方式

✅ 情况 1:32 位程序跑在 32 位系统

  • 用普通 readdir
  • 若文件多 / inode 大 → 加 _FILE_OFFSET_BITS=64

✅ 情况 2:32 位程序跑在 64 位系统

  • 必须用 64 位 inode 支持
  • glibc 会自动重定向:
    readdir → readdir64
    
    只要你定义了:
    #define _FILE_OFFSET_BITS 64
    

✅ 情况 3:32 位程序调用 64 位库

  • ❌ 不兼容
  • 必须:
    • 用 32 位库
    • 或改成 64 位程序

四、推荐的安全写法(兼容 32/64)

#define _FILE_OFFSET_BITS 64
#include <dirent.h>
#include <stdio.h>

int main() {
    DIR *dir = opendir(".");
    struct dirent *entry;

    while ((entry = readdir(dir)) != NULL) {
        printf("%s\n", entry->d_name);
    }

    closedir(dir);
    return 0;
}

编译:

gcc -m32 -D_FILE_OFFSET_BITS=64 test.c

五、readdir vs readdir64 对照

函数 适用
readdir 默认(可能被重定向)
readdir64 明确 64 位 inode
readdir_r 已废弃
getdents64 系统调用级

六、调试技巧

file a.out
ldd a.out
getconf LONG_BIT

如果看到:

errno = EOVERFLOW

基本就是 32 位 inode 不够用。


七、一句话总结

Linux readdir 兼容 32 位的关键:

  • 32 位程序必须开 _FILE_OFFSET_BITS=64
  • 或直接使用 readdir64
  • 不要混用 32/64 位库

如果你有具体场景(交叉编译 / 容器 / 老系统 / 嵌入式),我可以给你更针对性的方案。

0 踩