温馨提示×

centos readdir怎么重写

小樊
46
2026-08-30 10:16:06
栏目: 智能运维

在 CentOS(或一般 Linux)里,“重写 readdir”通常有几种不同含义,取决于你想在哪里、以什么方式重写它。下面按常见场景给你说明,并给出示例。


一、如果只是“自己实现 readdir”(用户态,最常见)

readdir 是 glibc 提供的函数,用于读取目录内容。
不能直接修改 glibc,但可以通过 符号介入(symbol interposition)封装函数 的方式“重写”。

方式 1:使用 LD_PRELOAD 重写 readdir(推荐)

1️⃣ 自己写一个 readdir.c

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

struct dirent *readdir(DIR *dirp) {
    static struct dirent *(*original_readdir)(DIR *) = NULL;

    if (!original_readdir) {
        original_readdir = dlsym(RTLD_NEXT, "readdir");
    }

    struct dirent *entry;
    while ((entry = original_readdir(dirp)) != NULL) {
        // 示例:过滤掉 . 和 ..
        if (strcmp(entry->d_name, ".") == 0 ||
            strcmp(entry->d_name, "..") == 0) {
            continue;
        }
        return entry;
    }
    return NULL;
}

2️⃣ 编译成共享库(CentOS 7/8 通用)

gcc -fPIC -shared -o myreaddir.so readdir.c -ldl

3️⃣ 使用

export LD_PRELOAD=./myreaddir.so
ls

✅ 此时 ls 实际调用的是你重写的 readdir


二、如果你是在写程序,只是不想用系统的 readdir

方式:自己封装一个函数

#include <dirent.h>
#include <stdio.h>

DIR *my_opendir(const char *path) {
    return opendir(path);
}

struct dirent *my_readdir(DIR *dirp) {
    struct dirent *entry;
    while ((entry = readdir(dirp)) != NULL) {
        if (entry->d_name[0] != '.') {
            return entry;
        }
    }
    return NULL;
}

✅ 不影响系统函数,最安全


三、如果你想“修改内核中的 readdir”(高级 / 不推荐)

情况说明

  • readdir 在内核中是 getdents / getdents64
  • 真正的目录读取逻辑在 文件系统层(ext4 / xfs / overlayfs)

可修改位置

位置 说明
fs/readdir.c 用户态 → 内核态的入口
struct file_operations 中的 .iterate 具体文件系统实现
LSM / eBPF 更安全的方式

⚠️ 不建议直接改内核

  • 不稳定
  • 升级内核会丢
  • CentOS 内核版本变化大

四、如果你想“过滤目录内容”(推荐方案)

✅ 用 eBPF(CentOS 8+)

bpftrace -e '
tracepoint:syscalls:sys_enter_getdents {
    printf("getdents called by %s\n", comm);
}'

或者写 BPF LSM 过滤文件名


五、常见问题

❓ 为什么不直接 #define readdir

#define readdir my_readdir  // ❌ 不安全

会导致 glibc 内部调用混乱,强烈不推荐。

❓ CentOS 7 能用吗?

✅ 能,glibc + LD_PRELOAD 完全支持


六、总结(推荐顺序)

  1. LD_PRELOAD 重写 readdir(最常见)
  2. 自己封装函数
  3. ⚠️ 内核 / eBPF(只在安全、监控、审计场景)

如果你能告诉我:

  • 是想 过滤目录
  • 还是 做安全 / 沙箱
  • 还是 调试 / 审计
  • 还是 文件系统开发

我可以直接给你最合适的实现方案 + 完整代码

0