From: Andy Pan Date: Sun, 6 Apr 2025 12:37:10 +0000 (+0800) Subject: socketpair: support pipe2 where available X-Git-Tag: curl-8_14_0~342 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=131a2fd5aaa1a809211695d2ef8151ffadbebc0c;p=thirdparty%2Fcurl.git socketpair: support pipe2 where available By replacing pipe with pipe2, it would save us 4 extra system calls of setting O_NONBLOCK and O_CLOEXEC. This system call is widely supported across UNIX-like OS's: Linux, *BSD, and SunOS derivatives - Solaris, illumos, etc. Ref: https://man7.org/linux/man-pages/man2/pipe.2.html https://man.freebsd.org/cgi/man.cgi?query=pipe https://man.dragonflybsd.org/?command=pipe2 https://man.netbsd.org/pipe.2 https://man.openbsd.org/pipe.2 https://docs.oracle.com/cd/E88353_01/html/E37841/pipe2-2.html https://illumos.org/man/2/pipe2 https://www.gnu.org/software/gnulib/manual/html_node/pipe2.html Closes #16987 --- diff --git a/CMake/unix-cache.cmake b/CMake/unix-cache.cmake index d97709bcf0..58da04e222 100644 --- a/CMake/unix-cache.cmake +++ b/CMake/unix-cache.cmake @@ -192,6 +192,15 @@ set(HAVE_NETINET_UDP_H 1) set(HAVE_NET_IF_H 1) set(HAVE_OPENDIR 1) set(HAVE_PIPE 1) +if(APPLE OR + CYGWIN) + set(HAVE_PIPE2 0) +elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR + CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR + CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR + CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + set(HAVE_PIPE2 1) +endif() set(HAVE_POLL 1) set(HAVE_POLL_H 1) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") diff --git a/CMake/win32-cache.cmake b/CMake/win32-cache.cmake index aac0678e75..5bf8f203fb 100644 --- a/CMake/win32-cache.cmake +++ b/CMake/win32-cache.cmake @@ -139,6 +139,7 @@ set(HAVE_NETINET_TCP_H 0) set(HAVE_NETINET_UDP_H 0) set(HAVE_NET_IF_H 0) set(HAVE_PIPE 0) +set(HAVE_PIPE2 0) set(HAVE_POLL 0) set(HAVE_POLL_H 0) set(HAVE_POSIX_STRERROR_R 0) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38c7847a32..7edaf518b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,7 +281,7 @@ endif() include(PickyWarnings) -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") +if(CYGWIN OR CMAKE_SYSTEM_NAME STREQUAL "Linux") string(APPEND CMAKE_C_FLAGS " -D_GNU_SOURCE") # Required for sendmmsg() and accept4() endif() @@ -1772,6 +1772,7 @@ check_symbol_exists("getaddrinfo" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_ check_symbol_exists("getifaddrs" "${CURL_INCLUDES};stdlib.h" HAVE_GETIFADDRS) # ifaddrs.h check_symbol_exists("freeaddrinfo" "${CURL_INCLUDES}" HAVE_FREEADDRINFO) # ws2tcpip.h sys/socket.h netdb.h check_function_exists("pipe" HAVE_PIPE) +check_function_exists("pipe2" HAVE_PIPE2) check_function_exists("eventfd" HAVE_EVENTFD) check_symbol_exists("ftruncate" "unistd.h" HAVE_FTRUNCATE) check_symbol_exists("getpeername" "${CURL_INCLUDES}" HAVE_GETPEERNAME) # winsock2.h unistd.h proto/bsdsocket.h diff --git a/configure.ac b/configure.ac index fde12e559f..f99548e290 100644 --- a/configure.ac +++ b/configure.ac @@ -577,7 +577,7 @@ AM_CONDITIONAL(BUILD_UNITTESTS, test x$supports_unittests = xyes) # In order to detect support of sendmmsg() and accept4(), we need to escape the POSIX # jail by defining _GNU_SOURCE or will not expose it. case $host_os in - linux*) + linux*|cygwin*|msys*) CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" ;; esac @@ -4124,6 +4124,7 @@ AC_CHECK_FUNCS([\ gettimeofday \ mach_absolute_time \ pipe \ + pipe2 \ poll \ sendmmsg \ sendmsg \ diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake index 12d513cce9..90f7d51459 100644 --- a/lib/curl_config.h.cmake +++ b/lib/curl_config.h.cmake @@ -430,6 +430,9 @@ /* Define to 1 if you have the `pipe' function. */ #cmakedefine HAVE_PIPE 1 +/* Define to 1 if you have the `pipe2' function. */ +#cmakedefine HAVE_PIPE2 1 + /* Define to 1 if you have the `eventfd' function. */ #cmakedefine HAVE_EVENTFD 1 diff --git a/lib/socketpair.c b/lib/socketpair.c index e4ca2cffa0..cfca37bf13 100644 --- a/lib/socketpair.c +++ b/lib/socketpair.c @@ -50,6 +50,11 @@ int Curl_eventfd(curl_socket_t socks[2], bool nonblocking) int Curl_pipe(curl_socket_t socks[2], bool nonblocking) { +#ifdef HAVE_PIPE2 + int flags = nonblocking ? O_NONBLOCK | O_CLOEXEC : O_CLOEXEC; + if(pipe2(socks, flags)) + return -1; +#else if(pipe(socks)) return -1; #ifdef HAVE_FCNTL @@ -70,6 +75,7 @@ int Curl_pipe(curl_socket_t socks[2], bool nonblocking) return -1; } } +#endif return 0; }