包含 unistd.h 的 write() 包装例程会导致错误

Lip*_*eka 4 c linux wrapper

我正在编写一个包装例程来write()覆盖原始系统函数,并且在其中我需要通过执行另一个程序execve();我为其添加了头文件unistd.h。我得到了错误conflicting types for 'write' /usr/include/unistd.h:363:16: note: previous declaration of 'write'was here。如果有人可以帮助我,我将非常感激,因为我需要从包装器内部调用另一个程序,并从包装器例程内部向它发送参数。

Mat*_*ery 5

GNU 链接器有一个--wrap <symbol>选项允许您执行此类操作。

如果您使用 链接--wrap write,对 的引用write将重定向到__wrap_write(您实现的),对 的引用__real_write将重定向到原始文件write(因此您可以从包装器实现中调用它)。

这是一个复杂的测试应用程序,使用write()- 我正在分别执行编译和链接步骤,因为我想hello.o在一分钟内再次使用:

$ cat hello.c
#include <unistd.h>

int main(void)
{
    write(0, "Hello, world!\n", 14);
    return 0;
}
$ gcc -Wall -c hello.c
$ gcc -o test1 hello.o
$ ./test1
Hello, world!
$
Run Code Online (Sandbox Code Playgroud)

这是 的一个实现__wrap_write(),它调用__real_write(). (请注意,我们需要一个原型来__real_write匹配原始原型。我已经显式添加了一个匹配原型,但另一个可能的选择是#define write __real_write before #include <unistd.h>。)

$ cat wrapper.c
#include <unistd.h>

extern ssize_t __real_write(int fd, const void *buf, size_t n);

ssize_t __wrap_write(int fd, const void *buf, size_t n)
{
    __real_write(fd, "[wrapped] ", 10);
    return __real_write(fd, buf, n);
}
$ gcc -Wall -c wrapper.c
$
Run Code Online (Sandbox Code Playgroud)

现在,将hello.o我们之前创建的 与链接起来wrapper.o,将适当的标志传递给链接器。gcc(我们可以使用稍微奇怪的语法将任意选项传递给链接器-Wl,option。)

$ gcc -o test2 -Wl,--wrap -Wl,write hello.o wrapper.o
$ ./test2
[wrapped] Hello, world!
$
Run Code Online (Sandbox Code Playgroud)