Commit b2eaf870 authored by Pekka Paalanen's avatar Pekka Paalanen

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's avatarPekka Paalanen <ppaalanen@gmail.com>
parent 35d5053c
......@@ -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;
......
......@@ -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);
}
......@@ -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.
......
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment