6

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

这是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显示。close(3)ls

关于什么可能是错误的任何想法?

4

2 回答 2

2

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

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

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

于 2014-04-28T17:05:44.147 回答
1

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

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

于 2014-04-28T16:20:51.797 回答