commit 5e7d572a52a8fe6774d3b5d3177eb12461a234b7
Author: Yawning Angel <yawning(a)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(a)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:
/*