diff --git a/adapter/syscall/ff_declare_syscalls.h b/adapter/syscall/ff_declare_syscalls.h index 8be24efa9..9f2cc0c01 100644 --- a/adapter/syscall/ff_declare_syscalls.h +++ b/adapter/syscall/ff_declare_syscalls.h @@ -22,7 +22,6 @@ FF_SYSCALL_DECL(ssize_t, recvfrom, (int, void *, size_t, int, FF_SYSCALL_DECL(ssize_t, sendmsg, (int, const struct msghdr *, int flags)); FF_SYSCALL_DECL(ssize_t, recvmsg, (int, struct msghdr *, int flags)); FF_SYSCALL_DECL(int, close, (int)); -FF_SYSCALL_DECL(int, ioctl, (int, unsigned long, unsigned long)); FF_SYSCALL_DECL(int, fcntl, (int, int, unsigned long)); FF_SYSCALL_DECL(int, epoll_create, (int)); FF_SYSCALL_DECL(int, epoll_ctl, (int, int, int, struct epoll_event *)); diff --git a/adapter/syscall/ff_hook_syscall.c b/adapter/syscall/ff_hook_syscall.c index 77093287a..8b5827d76 100644 --- a/adapter/syscall/ff_hook_syscall.c +++ b/adapter/syscall/ff_hook_syscall.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -1882,6 +1883,25 @@ ff_hook_ioctl(int fd, unsigned long req, unsigned long data) RETURN_NOFREE(); } +/* + * Public ioctl() entry point with variadic signature matching glibc's + * declaration: int ioctl(int fd, unsigned long request, ...) + * This avoids the 'conflicting types' compile error when strong_alias is + * used against the fixed-arg ff_hook_ioctl prototype (issue #942). + */ +int +ioctl(int fd, unsigned long req, ...) +{ + va_list ap; + unsigned long data; + + va_start(ap, req); + data = va_arg(ap, unsigned long); + va_end(ap); + + return ff_hook_ioctl(fd, req, data); +} + int ff_hook_fcntl(int fd, int cmd, unsigned long data) { diff --git a/adapter/syscall/ff_linux_syscall.c b/adapter/syscall/ff_linux_syscall.c index dbc3a78df..cd81c4b79 100644 --- a/adapter/syscall/ff_linux_syscall.c +++ b/adapter/syscall/ff_linux_syscall.c @@ -22,6 +22,8 @@ struct ff_linux_syscall { #define FF_SYSCALL_DECL(ret, fn, args) ret (*pf_##fn) args; #include "ff_declare_syscalls.h" + /* ioctl removed from ff_declare_syscalls.h (issue #942 fix), add manually */ + int (*pf_ioctl)(int, unsigned long, unsigned long); }; static int linux_syscall_inited; @@ -44,6 +46,8 @@ linux_syscall_load_symbol() #define FF_SYSCALL_DECL(ret, fn, args) \ syscalls.pf_##fn = (typeof(syscalls.pf_##fn))dlsym(linux_lib_handle, #fn); #include + /* ioctl removed from ff_declare_syscalls.h (issue #942 fix), load manually */ + syscalls.pf_ioctl = (typeof(syscalls.pf_ioctl))dlsym(linux_lib_handle, "ioctl"); return 0; } diff --git a/adapter/syscall/ff_linux_syscall.h b/adapter/syscall/ff_linux_syscall.h index c6fc96582..46a0f2229 100644 --- a/adapter/syscall/ff_linux_syscall.h +++ b/adapter/syscall/ff_linux_syscall.h @@ -10,4 +10,8 @@ #define FF_SYSCALL_DECL(ret, fn, args) ret ff_linux_##fn args #include "ff_declare_syscalls.h" +/* ioctl is removed from ff_declare_syscalls.h (variadic conflict fix, issue #942), + * declare ff_linux_ioctl explicitly here. */ +int ff_linux_ioctl(int fd, unsigned long req, unsigned long data); + #endif