Although John Bollinger is correct in that according to its prototype in ioctl.h
, ioctl()
is a variadic function, in practice, it is not.
See e.g this quote from the book 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.
So you can write your susbtitute ioctl()
as follows:
int ioctl(int d, unsigned long request, char *argp)
{
/* follow the same recipe as for your example gettimeofday() */
return ioctl_real(d, request, argp);
}
If you just want to build a wrapper library for use with LD_PRELOAD
, the fact that your ioctl
signature contradicts the one in sys/ioctl.h
is irrelevant: linkers don't check types, and your wrapper library's fake ioctl
will be called with exactly the same arguments as the real one would without LD_PRELOAD