我正在尝试在Linux中提供我自己的close()
函数实现。为什么?因为我发现你可以做到这一点,听起来很有趣。
这是myclose.c:
#include <stdio.h>
int close(int fd) {
printf("Closing fd: %d\n", fd);
return 0;
}
这是我的makefile:
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()
,但我们只看到一行输出。根据{{1}}(和常识),也应该为文件描述符1和2调用strace
。如果我运行close()
并捕获目录中的所有文件,我会看到“关闭fd:3”,“关闭fd:4”等,直到目录中的最后一个文件。由于所有这些文件描述符都大于2,我想可能在关闭特殊文件描述符(stdout和stderr)时存在问题。但是,当我运行cat *
时,我只看到常规输出而没有“关闭fd:”行,这意味着它也不适用于ls
,即使ls
显示{{ 1}}运行strace
时。
关于什么可能出错的任何想法?
答案 0 :(得分:2)
这种“替代”仅适用于动态链接的程序。
任何与实现close
- 调用的库静态链接的程序都无法将其“替换”。
后者将是实现原始close()
本身的库中每次调用close()
的情况。标准文件描述符0
,1
和2
似乎也是如此,因为它们最有可能在同一个库中实现,即在libc实现中使用
答案 1 :(得分:1)
我感到惊讶它的效果和它一样好!
您正在替换close()的C库条目,而不是系统调用。但是,C库的其他部分仍然用于这些程序。可能有一些直接链接到前3个文件句柄。看看你正在使用的C库的来源。