Commit ff50f6bf authored by Pekka Paalanen's avatar Pekka Paalanen

os: wrap accept4(SOCK_CLOEXEC)

Some system C libraries do not have SOCK_CLOEXEC, and completely miss
accept4(), too. Provide a fallback for this case.

This changes the behaviour: no error messages are printed now for
failing to set CLOEXEC but the file descriptor is closed.

The unit test for this wrapper is NOT included.
Signed-off-by: Pekka Paalanen's avatarPekka Paalanen <ppaalanen@gmail.com>
parent b2eaf870
......@@ -39,6 +39,8 @@ if test "x$GCC" = "xyes"; then
fi
AC_SUBST(GCC_CFLAGS)
AC_CHECK_FUNCS([accept4])
AC_ARG_ENABLE([scanner],
[AC_HELP_STRING([--disable-scanner],
[Disable compilation of wayland-scannner])],
......
......@@ -20,6 +20,8 @@
* OF THIS SOFTWARE.
*/
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
......@@ -27,6 +29,7 @@
#include <errno.h>
#include <sys/epoll.h>
#include "../config.h"
#include "wayland-os.h"
static int
......@@ -142,3 +145,20 @@ wl_os_epoll_create_cloexec(void)
fd = epoll_create(1);
return set_cloexec_or_close(fd);
}
int
wl_os_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
int fd;
#ifdef HAVE_ACCEPT4
fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);
if (fd >= 0)
return fd;
if (errno != ENOSYS)
return -1;
#endif
fd = accept(sockfd, addr, addrlen);
return set_cloexec_or_close(fd);
}
......@@ -35,6 +35,9 @@ wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags);
int
wl_os_epoll_create_cloexec(void);
int
wl_os_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
/*
* The following are for wayland-os.c and the unit tests.
......
......@@ -902,14 +902,8 @@ socket_data(int fd, uint32_t mask, void *data)
int client_fd;
length = sizeof name;
client_fd =
accept4(fd, (struct sockaddr *) &name, &length, SOCK_CLOEXEC);
if (client_fd < 0 && errno == ENOSYS) {
client_fd = accept(fd, (struct sockaddr *) &name, &length);
if (client_fd >= 0 && fcntl(client_fd, F_SETFD, FD_CLOEXEC) == -1)
fprintf(stderr, "failed to set FD_CLOEXEC flag on client fd, errno: %d\n", errno);
}
client_fd = wl_os_accept_cloexec(fd, (struct sockaddr *) &name,
&length);
if (client_fd < 0)
fprintf(stderr, "failed to accept, errno: %d\n", errno);
......
......@@ -382,3 +382,5 @@ TEST(os_wrappers_epoll_create_cloexec_fallback)
init_fallbacks(1);
do_os_wrappers_epoll_create_cloexec(2);
}
/* FIXME: add tests for wl_os_accept_cloexec() */
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