commit 5e7d572a52a8fe6774d3b5d3177eb12461a234b7 Author: Yawning Angel yawning@schwanenlied.me Date: Tue Apr 7 11:10:47 2015 +0000
Support the various epoll routines when invoked via syscall().
Signed-off-by: Yawning Angel yawning@schwanenlied.me --- src/common/compat.h | 26 +++++++++++++++++ src/lib/syscall.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+)
diff --git a/src/common/compat.h b/src/common/compat.h index b4bef9a..8c3be78 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -111,6 +111,32 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m); #define TSOCKS_NR_FUTEX __NR_futex #define TSOCKS_NR_ACCEPT4 __NR_accept4
+/* + * Despite glibc providing wrappers for these calls for a long time + * (as in "even Debian squeeze has all the wrappers"), libuv decided to + * use syscall() to invoke them instead. + */ + +#include <sys/epoll.h> + +#ifndef __NR_epoll_create1 +#define __NR_epoll_create1 -128 +#endif +#ifndef __NR_epoll_wait +#define __NR_epoll_wait -129 +#endif +#ifndef __NR_epoll_pwait +#define __NR_epoll_pwait -130 +#endif +#ifndef __NR_epoll_ctl +#define __NR_epoll_ctl -131 +#endif + +#define TSOCKS_NR_EPOLL_CREATE1 __NR_epoll_create1 +#define TSOCKS_NR_EPOLL_WAIT __NR_epoll_wait +#define TSOCKS_NR_EPOLL_PWAIT __NR_epoll_pwait +#define TSOCKS_NR_EPOLL_CTL __NR_epoll_ctl + #endif /* __linux__ */
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__darwin__) || defined(__NetBSD__)) diff --git a/src/lib/syscall.c b/src/lib/syscall.c index 5dad3ce..c6585a8 100644 --- a/src/lib/syscall.c +++ b/src/lib/syscall.c @@ -230,6 +230,74 @@ static LIBC_SYSCALL_RET_TYPE handle_accept4(va_list args)
return tsocks_accept4(sockfd, addr, &addrlen, flags); } + +/* + * Handle epoll_create1(2) syscall. + */ +static LIBC_SYSCALL_RET_TYPE handle_epoll_create1(va_list args) +{ + int flags; + + flags = va_arg(args, __typeof__(flags)); + + return epoll_create1(flags); +} + +/* + * Handle epoll_wait(2) syscall. + */ +static LIBC_SYSCALL_RET_TYPE handle_epoll_wait(va_list args) +{ + int epfd; + struct epoll_event *events; + int maxevents; + int timeout; + + epfd = va_arg(args, __typeof__(epfd)); + events = va_arg(args, __typeof__(events)); + maxevents = va_arg(args, __typeof__(maxevents)); + timeout = va_arg(args, __typeof__(maxevents)); + + return epoll_wait(epfd, events, maxevents, timeout); +} + +/* + * Handle epoll_pwait(2) syscall. + */ +static LIBC_SYSCALL_RET_TYPE handle_epoll_pwait(va_list args) +{ + int epfd; + struct epoll_event *events; + int maxevents; + int timeout; + const sigset_t *sigmask; + + epfd = va_arg(args, __typeof__(epfd)); + events = va_arg(args, __typeof__(events)); + maxevents = va_arg(args, __typeof__(maxevents)); + timeout = va_arg(args, __typeof__(maxevents)); + sigmask = va_arg(args, __typeof__(sigmask)); + + return epoll_pwait(epfd, events, maxevents, timeout, sigmask); +} + +/* + * Handle epoll_ctl(2) syscall. + */ +static LIBC_SYSCALL_RET_TYPE handle_epoll_ctl(va_list args) +{ + int epfd; + int op; + int fd; + struct epoll_event *event; + + epfd = va_arg(args, __typeof__(epfd)); + op = va_arg(args, __typeof__(op)); + fd = va_arg(args, __typeof__(fd)); + event = va_arg(args, __typeof__(event)); + + return epoll_ctl(epfd, op, fd, event); +} #endif /* __linux__ */
/* @@ -309,6 +377,18 @@ LIBC_SYSCALL_RET_TYPE tsocks_syscall(long int number, va_list args) case TSOCKS_NR_ACCEPT4: ret = handle_accept4(args); break; + case TSOCKS_NR_EPOLL_CREATE1: + ret = handle_epoll_create1(args); + break; + case TSOCKS_NR_EPOLL_WAIT: + ret = handle_epoll_wait(args); + break; + case TSOCKS_NR_EPOLL_PWAIT: + ret = handle_epoll_pwait(args); + break; + case TSOCKS_NR_EPOLL_CTL: + ret = handle_epoll_ctl(args); + break; #endif /* __linux__ */ default: /*