这是我使用 LD_PRELOAD 包装函数的模板:
int gettimeofday(struct timeval *tv, struct timezone *tz) {
static int (*gettimeofday_real)(struct timeval *tv, struct timezone *tz)=NULL;
if (!gettimeofday_real) gettimeofday_real=dlsym(RTLD_NEXT,"gettimeofday");
return gettimeofday_real(tv, tz);
}
我意识到 ioctl 似乎具有以下签名:
int ioctl(int d, unsigned long request, ...);
鉴于签名中的 ...
,我如何以类似的方式包装它?
最佳答案
虽然 John Bollinger 是正确的,根据其在 ioctl.h
中的原型(prototype),ioctl()
是一个可变参数函数,但实际上并非如此。
参见例如 this quote来自书Linux Device Drivers
The prototype stands out in the list of Unix system calls because of the dots, which usually mark the function as having a variable number of arguments. In a real system, however, a system call can't actually have a variable number of arguments. System calls must have a well-defined prototype, because user programs can access them only through hardware "gates." Therefore, the dots in the prototype represent not a variable number of arguments but a single optional argument, traditionally identified as char *argp. The dots are simply there to prevent type checking during compilation.
所以你可以写你的 susbtitute ioctl()
如下:
int ioctl(int d, unsigned long request, char *argp)
{
/* follow the same recipe as for your example gettimeofday() */
return ioctl_real(d, request, argp);
}
如果您只是想构建一个用于 LD_PRELOAD
的包装器库,那么您的 ioctl
签名与 sys/ioctl.h< 中的签名相矛盾这一事实
是无关紧要的:链接器不检查类型,你的包装器库的假 ioctl
将使用与没有 LD_PRELOAD
的真实库完全相同的参数调用p>
关于c - 如何使用 LD_PRELOAD 包装 ioctl(int d, unsigned long request, ...)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28462523/