温馨提示×

centos readdir怎么重载

小樊
41
2026-09-15 06:56:00
栏目: 智能运维

CentOS(Linux) 上,“重载 readdir” 一般有两种理解,下面分别说明,你可以看哪种符合你的需求。


一、运行时“重载” readdir(函数替换 / Hook)

如果你的意思是:

不修改程序源码,让程序调用你自己的 readdir 实现

可以用 LD_PRELOAD 方式拦截 readdir / readdir64

示例:自定义 readdir

#define _GNU_SOURCE
#include <dirent.h>
#include <string.h>
#include <stdio.h>

struct dirent *readdir(DIR *dirp) {
    struct dirent *entry;
    static int count = 0;

    while ((entry = readdir64(dirp)) != NULL) {
        // 过滤掉 . 和 ..
        if (strcmp(entry->d_name, ".") == 0 ||
            strcmp(entry->d_name, "..") == 0)
            continue;

        printf("[hook] readdir: %s\n", entry->d_name);
        return entry;
    }
    return NULL;
}

编译:

gcc -shared -fPIC -o readdir_hook.so readdir_hook.c -ldl

使用:

LD_PRELOAD=./readdir_hook.so ls

✅ 适用于:

  • 调试
  • 文件过滤
  • 安全审计
  • 故障注入

⚠ 注意:

  • glibc 中实际常用的是 readdir64
  • 某些程序静态链接或 setuid 时无效

二、文件系统层“重载” readdir(开发文件系统)

如果你的意思是:

自己实现一个文件系统的 readdir 行为

那需要使用 FUSE内核模块

1️⃣ FUSE(推荐,用户态)

CentOS 安装:

yum install fuse fuse-devel

FUSE 中重写:

static int my_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                      off_t offset, struct fuse_file_info *fi)
{
    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    filler(buf, "hello.txt", NULL, 0);
    return 0;
}

适合:

  • 虚拟文件系统
  • 云存储挂载
  • 特殊目录行为

2️⃣ 内核模块(不推荐新手)

需要:

  • file_operations.readdir
  • 重写 vfs_readdir
  • 仅限内核开发

三、总结对照

需求 方法
拦截已有程序的 readdir LD_PRELOAD
自定义目录内容 FUSE
修改内核行为 内核模块

如果你能具体说一下:

  • 应用程序 还是 系统级
  • 过滤 / 修改 / 调试 / 性能

我可以给你更精确的代码或方案。

0