From ac552ba44891b3240e4a55d29ff7b4f6de692204 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 17 Nov 2017 18:40:53 +0000 Subject: [PATCH] Problem: accept4 not available on all platforms Solution: check for availability in CMake and autoconf before using it --- CMakeLists.txt | 4 ++++ NEWS | 3 +++ builds/cmake/platform.hpp.in | 1 + builds/gyp/platform.hpp | 1 + configure.ac | 2 +- src/ipc_listener.cpp | 4 ++-- src/tcp_listener.cpp | 4 ++-- 7 files changed, 14 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36b3e333..d9f59722 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -236,6 +236,10 @@ set (CMAKE_REQUIRED_INCLUDES stdlib.h) check_function_exists (mkdtemp HAVE_MKDTEMP) set (CMAKE_REQUIRED_INCLUDES) +set (CMAKE_REQUIRED_INCLUDES sys/socket.h) +check_function_exists (accept4 HAVE_ACCEPT4) +set (CMAKE_REQUIRED_INCLUDES) + add_definitions (-D_REENTRANT -D_THREAD_SAFE) add_definitions (-DZMQ_CUSTOM_PLATFORM_HPP) diff --git a/NEWS b/NEWS index 2e9046cb..da146dfc 100644 --- a/NEWS +++ b/NEWS @@ -212,6 +212,9 @@ * Fixed #2809 - optimize select() usage on Windows +* Fixed #2816 - add CMake and autoconf check for accept4, as it is not + available on old Linux releases, and fallback to accept + FD_CLOEXEC + * Fixed #2824 - ZMQ_REQ socket does not report ZMQ_POLLOUT when ZMQ_REQ_RELAXED is set diff --git a/builds/cmake/platform.hpp.in b/builds/cmake/platform.hpp.in index 7437bb98..18d02d2b 100644 --- a/builds/cmake/platform.hpp.in +++ b/builds/cmake/platform.hpp.in @@ -36,6 +36,7 @@ #cmakedefine ZMQ_HAVE_PTHREAD_SETNAME_2 #cmakedefine ZMQ_HAVE_PTHREAD_SETNAME_3 #cmakedefine ZMQ_HAVE_PTHREAD_SET_NAME +#cmakedefine HAVE_ACCEPT4 #cmakedefine ZMQ_HAVE_OPENPGM #cmakedefine ZMQ_MAKE_VALGRIND_HAPPY diff --git a/builds/gyp/platform.hpp b/builds/gyp/platform.hpp index d80bb845..c463ca19 100644 --- a/builds/gyp/platform.hpp +++ b/builds/gyp/platform.hpp @@ -71,6 +71,7 @@ # define ZMQ_HAVE_UIO 1 # define HAVE_CLOCK_GETTIME 1 # define HAVE_FORK 1 +# define HAVE_ACCEPT4 1 #else # error "No platform defined, abandoning" diff --git a/configure.ac b/configure.ac index 7712917d..61267e25 100644 --- a/configure.ac +++ b/configure.ac @@ -621,7 +621,7 @@ AC_LANG_POP([C++]) # Checks for library functions. AC_TYPE_SIGNAL -AC_CHECK_FUNCS(perror gettimeofday clock_gettime memset socket getifaddrs freeifaddrs fork posix_memalign mkdtemp) +AC_CHECK_FUNCS(perror gettimeofday clock_gettime memset socket getifaddrs freeifaddrs fork posix_memalign mkdtemp accept4) AC_CHECK_HEADERS([alloca.h]) # pthread_setname is non-posix, and there are at least 4 different implementations diff --git a/src/ipc_listener.cpp b/src/ipc_listener.cpp index 37e3454b..40e9ecba 100644 --- a/src/ipc_listener.cpp +++ b/src/ipc_listener.cpp @@ -382,7 +382,7 @@ zmq::fd_t zmq::ipc_listener_t::accept () // The situation where connection cannot be accepted due to insufficient // resources is considered valid and treated by ignoring the connection. zmq_assert (s != retired_fd); -#if defined ZMQ_HAVE_SOCK_CLOEXEC +#if defined ZMQ_HAVE_SOCK_CLOEXEC && defined HAVE_ACCEPT4 fd_t sock = ::accept4 (s, NULL, NULL, SOCK_CLOEXEC); #else fd_t sock = ::accept (s, NULL, NULL); @@ -394,7 +394,7 @@ zmq::fd_t zmq::ipc_listener_t::accept () return retired_fd; } -#if !defined ZMQ_HAVE_SOCK_CLOEXEC && defined FD_CLOEXEC +#if (!defined ZMQ_HAVE_SOCK_CLOEXEC || !defined HAVE_ACCEPT4) && defined FD_CLOEXEC // Race condition can cause socket not to be closed (if fork happens // between accept and this point). int rc = fcntl (sock, F_SETFD, FD_CLOEXEC); diff --git a/src/tcp_listener.cpp b/src/tcp_listener.cpp index 7fb05c98..7b929d42 100644 --- a/src/tcp_listener.cpp +++ b/src/tcp_listener.cpp @@ -281,7 +281,7 @@ zmq::fd_t zmq::tcp_listener_t::accept () #else socklen_t ss_len = sizeof (ss); #endif -#if defined ZMQ_HAVE_SOCK_CLOEXEC +#if defined ZMQ_HAVE_SOCK_CLOEXEC && defined HAVE_ACCEPT4 fd_t sock = ::accept4 (s, (struct sockaddr *) &ss, &ss_len, SOCK_CLOEXEC); #else fd_t sock = ::accept (s, (struct sockaddr *) &ss, &ss_len); @@ -311,7 +311,7 @@ zmq::fd_t zmq::tcp_listener_t::accept () } #endif -#if !defined ZMQ_HAVE_SOCK_CLOEXEC && defined FD_CLOEXEC +#if (!defined ZMQ_HAVE_SOCK_CLOEXEC || !defined HAVE_ACCEPT4) && defined FD_CLOEXEC // Race condition can cause socket not to be closed (if fork happens // between accept and this point). int rc = fcntl (sock, F_SETFD, FD_CLOEXEC);