From: Pekka Paalanen Date: Thu, 22 Mar 2012 12:16:10 +0000 (+0200) Subject: os: wrap accept4(SOCK_CLOEXEC) X-Git-Tag: 0.94.90~83^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ff50f6bfc44bd072aa8806f976718d30468fa2c2;p=profile%2Fivi%2Fwayland.git 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 --- diff --git a/configure.ac b/configure.ac index 615dfdb..63081e1 100644 --- a/configure.ac +++ b/configure.ac @@ -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])], diff --git a/src/wayland-os.c b/src/wayland-os.c index a8756b6..1185e1d 100644 --- a/src/wayland-os.c +++ b/src/wayland-os.c @@ -20,6 +20,8 @@ * OF THIS SOFTWARE. */ +#define _GNU_SOURCE + #include #include #include @@ -27,6 +29,7 @@ #include #include +#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); +} diff --git a/src/wayland-os.h b/src/wayland-os.h index f6827f1..c612975 100644 --- a/src/wayland-os.h +++ b/src/wayland-os.h @@ -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. diff --git a/src/wayland-server.c b/src/wayland-server.c index 94eb308..e8173fb 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -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); diff --git a/tests/os-wrappers-test.c b/tests/os-wrappers-test.c index 967eb83..9c4e7b2 100644 --- a/tests/os-wrappers-test.c +++ b/tests/os-wrappers-test.c @@ -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() */