【问题标题】:Replacing the close() function in Linux with my own close() function用我自己的 close() 函数替换 Linux 中的 close() 函数
【发布时间】:2014-06-14 06:55:36
【问题描述】:

我正在尝试在 Linux 中提供我自己的 close() 函数实现。为什么?因为我刚刚发现你可以这样做,而且听起来很有趣。

这里是 myclose.c:

#include <stdio.h>

int close(int fd) {
    printf("Closing fd: %d\n", fd);
    return 0;
}

这是我的生成文件:

all: myclose.so my-close.so

%.so: %.o
    gcc -shared -o $@ $<

%.o:%.c
    gcc -c -fPIC -o $@ $<

clean:
    rm -f *.so *.o

编译后,我运行:

export LD_PRELOAD=`pwd`/myclose.so

然后我运行:

cat myclose.c

我得到的输出是:

#include <stdio.h>

int close(int fd) {
    printf("Closing fd: %d\n", fd);
    return 0;
}
Closing fd: 3

耶!工作正常吗?几乎。 cat 多次调用close(),但我们只看到一行输出。根据strace(和常识),close() 也应该为文件描述符 1 和 2 调用。如果我运行cat * 并 cat 目录中的所有文件,我会看到“Closing fd: 3”、“Closing fd: 4”等直到目录中的最后一个文件。由于所有这些文件描述符都大于 2,我认为关闭特殊文件描述符(stdout 和 stderr)可能存在问题。但是,当我运行ls 时,我只看到常规输出,没有“Closing fd:”行,这意味着它也不适用于ls,即使strace 在运行ls 时显示close(3) .

对可能出现的问题有任何想法吗?

【问题讨论】:

  • 我在这里可能完全错了,但是外壳不是在处理 FD 1 和 2 吗?您是否尝试过使用“close()”启动一个 shell 预加载它?

标签: c linux shared-libraries ld-preload


【解决方案1】:

这种“替换”只适用于动态链接的程序。

任何静态链接到实现close-调用的库的程序都无法“替换”它。

在实现原始close() 本身的库之外,每次调用close() 都会出现后者。标准文件描述符 012 似乎也是这种情况,因为它们的关闭很可能是在同一个库中实现的,即在使用的 libc 实现中。

【讨论】:

    【解决方案2】:

    我很惊讶它的效果和它一样好!

    您正在替换 close() 的 C 库条目,而不是系统调用。但是,这些程序仍在使用 C 库的其他部分。可能与前 3 个文件句柄有一些直接联系。查看您使用的任何 C 库的源代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-07
      • 2013-10-28
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多