mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-29 05:40:16 -04:00
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 <ppaalanen@gmail.com>
This commit is contained in:
parent
b2eaf870cf
commit
ff50f6bfc4
5 changed files with 29 additions and 8 deletions
|
|
@ -39,6 +39,8 @@ if test "x$GCC" = "xyes"; then
|
||||||
fi
|
fi
|
||||||
AC_SUBST(GCC_CFLAGS)
|
AC_SUBST(GCC_CFLAGS)
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS([accept4])
|
||||||
|
|
||||||
AC_ARG_ENABLE([scanner],
|
AC_ARG_ENABLE([scanner],
|
||||||
[AC_HELP_STRING([--disable-scanner],
|
[AC_HELP_STRING([--disable-scanner],
|
||||||
[Disable compilation of wayland-scannner])],
|
[Disable compilation of wayland-scannner])],
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
* OF THIS SOFTWARE.
|
* OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -27,6 +29,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
|
||||||
|
#include "../config.h"
|
||||||
#include "wayland-os.h"
|
#include "wayland-os.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -142,3 +145,20 @@ wl_os_epoll_create_cloexec(void)
|
||||||
fd = epoll_create(1);
|
fd = epoll_create(1);
|
||||||
return set_cloexec_or_close(fd);
|
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
|
int
|
||||||
wl_os_epoll_create_cloexec(void);
|
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.
|
* 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;
|
int client_fd;
|
||||||
|
|
||||||
length = sizeof name;
|
length = sizeof name;
|
||||||
client_fd =
|
client_fd = wl_os_accept_cloexec(fd, (struct sockaddr *) &name,
|
||||||
accept4(fd, (struct sockaddr *) &name, &length, SOCK_CLOEXEC);
|
&length);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client_fd < 0)
|
if (client_fd < 0)
|
||||||
fprintf(stderr, "failed to accept, errno: %d\n", errno);
|
fprintf(stderr, "failed to accept, errno: %d\n", errno);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -382,3 +382,5 @@ TEST(os_wrappers_epoll_create_cloexec_fallback)
|
||||||
init_fallbacks(1);
|
init_fallbacks(1);
|
||||||
do_os_wrappers_epoll_create_cloexec(2);
|
do_os_wrappers_epoll_create_cloexec(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: add tests for wl_os_accept_cloexec() */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue