summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <ppaalanen@gmail.com>2012-03-22 15:02:05 +0200
committerPekka Paalanen <ppaalanen@gmail.com>2012-04-25 09:37:42 +0300
commitb2eaf870cf8e8cb842ba29ea4718b596101252a6 (patch)
treece24bd654adfd6ad7f4634f86cc074cef2b1924c
parent35d5053c622a2b1502b71230c7755a8005b36301 (diff)
os: wrap epoll_create
Some system C libraries do not have epoll_create1() nor EPOLL_CLOEXEC, provide a fallback. Add tests for the wrapper. Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
-rw-r--r--src/event-loop.c3
-rw-r--r--src/wayland-os.c18
-rw-r--r--src/wayland-os.h3
-rw-r--r--tests/os-wrappers-test.c51
4 files changed, 74 insertions, 1 deletions
diff --git a/src/event-loop.c b/src/event-loop.c
index 3bab3df..ee2eae5 100644
--- a/src/event-loop.c
+++ b/src/event-loop.c
@@ -34,6 +34,7 @@
#include <unistd.h>
#include <assert.h>
#include "wayland-server.h"
+#include "wayland-os.h"
struct wl_event_loop {
int epoll_fd;
@@ -392,7 +393,7 @@ wl_event_loop_create(void)
if (loop == NULL)
return NULL;
- loop->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+ loop->epoll_fd = wl_os_epoll_create_cloexec();
if (loop->epoll_fd < 0) {
free(loop);
return NULL;
diff --git a/src/wayland-os.c b/src/wayland-os.c
index eb53eec..a8756b6 100644
--- a/src/wayland-os.c
+++ b/src/wayland-os.c
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <sys/epoll.h>
#include "wayland-os.h"
@@ -124,3 +125,20 @@ wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags)
return recvmsg_cloexec_fallback(sockfd, msg, flags);
}
+
+int
+wl_os_epoll_create_cloexec(void)
+{
+ int fd;
+
+#ifdef EPOLL_CLOEXEC
+ fd = epoll_create1(EPOLL_CLOEXEC);
+ if (fd >= 0)
+ return fd;
+ if (errno != EINVAL)
+ return -1;
+#endif
+
+ fd = epoll_create(1);
+ return set_cloexec_or_close(fd);
+}
diff --git a/src/wayland-os.h b/src/wayland-os.h
index 43c317b..f6827f1 100644
--- a/src/wayland-os.h
+++ b/src/wayland-os.h
@@ -32,6 +32,9 @@ wl_os_dupfd_cloexec(int fd, long minfd);
ssize_t
wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags);
+int
+wl_os_epoll_create_cloexec(void);
+
/*
* The following are for wayland-os.c and the unit tests.
diff --git a/tests/os-wrappers-test.c b/tests/os-wrappers-test.c
index 657f1fe..967eb83 100644
--- a/tests/os-wrappers-test.c
+++ b/tests/os-wrappers-test.c
@@ -34,6 +34,7 @@
#include <stdarg.h>
#include <fcntl.h>
#include <stdio.h>
+#include <sys/epoll.h>
#include "../src/wayland-private.h"
#include "test-runner.h"
@@ -50,6 +51,9 @@ static int wrapped_calls_fcntl;
static ssize_t (*real_recvmsg)(int, struct msghdr *, int);
static int wrapped_calls_recvmsg;
+static int (*real_epoll_create1)(int);
+static int wrapped_calls_epoll_create1;
+
static void
init_fallbacks(int do_fallbacks)
{
@@ -57,6 +61,7 @@ init_fallbacks(int do_fallbacks)
real_socket = dlsym(RTLD_NEXT, "socket");
real_fcntl = dlsym(RTLD_NEXT, "fcntl");
real_recvmsg = dlsym(RTLD_NEXT, "recvmsg");
+ real_epoll_create1 = dlsym(RTLD_NEXT, "epoll_create1");
}
__attribute__ ((visibility("default"))) int
@@ -105,6 +110,20 @@ recvmsg(int sockfd, struct msghdr *msg, int flags)
return real_recvmsg(sockfd, msg, flags);
}
+__attribute__ ((visibility("default"))) int
+epoll_create1(int flags)
+{
+ wrapped_calls_epoll_create1++;
+
+ if (fall_back) {
+ wrapped_calls_epoll_create1++; /* epoll_create() not wrapped */
+ errno = EINVAL;
+ return -1;
+ }
+
+ return real_epoll_create1(flags);
+}
+
static void
do_os_wrappers_socket_cloexec(int n)
{
@@ -331,3 +350,35 @@ TEST(os_wrappers_recvmsg_cloexec_fallback)
init_fallbacks(1);
do_os_wrappers_recvmsg_cloexec(1);
}
+
+static void
+do_os_wrappers_epoll_create_cloexec(int n)
+{
+ int fd;
+ int nr_fds;
+
+ nr_fds = count_open_fds();
+
+ fd = wl_os_epoll_create_cloexec();
+ assert(fd >= 0);
+
+#ifdef EPOLL_CLOEXEC
+ assert(wrapped_calls_epoll_create1 == n);
+#else
+ printf("No epoll_create1.\n");
+#endif
+
+ exec_fd_leak_check(nr_fds);
+}
+
+TEST(os_wrappers_epoll_create_cloexec)
+{
+ init_fallbacks(0);
+ do_os_wrappers_epoll_create_cloexec(1);
+}
+
+TEST(os_wrappers_epoll_create_cloexec_fallback)
+{
+ init_fallbacks(1);
+ do_os_wrappers_epoll_create_cloexec(2);
+}