[gcc r11-9141] libstdc++: Make Networking TS headers more portable [PR100285]

Jonathan Wakely redi@gcc.gnu.org
Tue Oct 12 19:41:38 GMT 2021


https://gcc.gnu.org/g:b7e73951fd15f07946ff0c56f4e31b0006c621f9

commit r11-9141-gb7e73951fd15f07946ff0c56f4e31b0006c621f9
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Aug 26 12:06:55 2021 +0100

    libstdc++: Make Networking TS headers more portable [PR100285]
    
    Add more preprocessor conditions to check for constants being defined
    before using them, so that the Networking TS headers can be compiled on
    a wider range of platforms.
    
    Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/100285
            * configure.ac: Check for O_NONBLOCK.
            * configure: Regenerate.
            * include/experimental/internet: Include <ws2tcpip.h> for
            Windows.  Use preprocessor conditions around more constants.
            * include/experimental/socket: Use preprocessor conditions
            around more constants.
            * testsuite/experimental/net/internet/resolver/base.cc: Only use
            constants when the corresponding C macro is defined.
            * testsuite/experimental/net/socket/basic_socket.cc: Likewise.
            * testsuite/experimental/net/socket/socket_base.cc: Likewise.
            Make preprocessor checks more fine-grained.

Diff:
---
 libstdc++-v3/configure                             | 84 +++++++++++++++++++---
 libstdc++-v3/configure.ac                          |  5 ++
 libstdc++-v3/include/experimental/internet         | 16 ++++-
 libstdc++-v3/include/experimental/socket           | 22 ++++--
 .../experimental/net/internet/resolver/base.cc     |  6 ++
 .../experimental/net/socket/basic_socket.cc        |  6 +-
 .../experimental/net/socket/socket_base.cc         | 12 ++--
 7 files changed, 129 insertions(+), 22 deletions(-)

diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 326a279c54f..16baffffc6c 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -2701,6 +2701,52 @@ $as_echo "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_cxx_check_type
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_c_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+  (void) $as_decl_use;
+#else
+  (void) $as_decl_name;
+#endif
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_decl
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -12130,7 +12176,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12133 "configure"
+#line 12179 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12236,7 +12282,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12239 "configure"
+#line 12285 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15918,7 +15964,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
   # Fake what AC_TRY_COMPILE does.
 
     cat > conftest.$ac_ext << EOF
-#line 15921 "configure"
+#line 15967 "configure"
 int main()
 {
   typedef bool atomic_type;
@@ -15953,7 +15999,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15956 "configure"
+#line 16002 "configure"
 int main()
 {
   typedef short atomic_type;
@@ -15988,7 +16034,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15991 "configure"
+#line 16037 "configure"
 int main()
 {
   // NB: _Atomic_word not necessarily int.
@@ -16024,7 +16070,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 16027 "configure"
+#line 16073 "configure"
 int main()
 {
   typedef long long atomic_type;
@@ -16177,7 +16223,7 @@ $as_echo "mutex" >&6; }
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 16180 "configure"
+#line 16226 "configure"
 int main()
 {
   _Decimal32 d1;
@@ -16219,7 +16265,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 16222 "configure"
+#line 16268 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
@@ -16253,7 +16299,7 @@ $as_echo "$enable_int128" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 16256 "configure"
+#line 16302 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
@@ -76748,6 +76794,26 @@ fi
 
 done
 
+ac_fn_c_check_decl "$LINENO" "F_GETFL" "ac_cv_have_decl_F_GETFL" "#include <fcntl.h>
+"
+if test "x$ac_cv_have_decl_F_GETFL" = xyes; then :
+
+fi
+
+ac_fn_c_check_decl "$LINENO" "F_SETFL" "ac_cv_have_decl_F_SETFL" "#include <fcntl.h>
+"
+if test "x$ac_cv_have_decl_F_SETFL" = xyes; then :
+
+fi
+
+if test "$ac_cv_have_decl_F_GETFL$ac_cv_have_decl_F_SETFL" = yesyes ; then
+  ac_fn_c_check_decl "$LINENO" "O_NONBLOCK" "ac_cv_have_decl_O_NONBLOCK" "#include <fcntl.h>
+"
+if test "x$ac_cv_have_decl_O_NONBLOCK" = xyes; then :
+
+fi
+
+fi
 
 # For Transactional Memory TS
 
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 3c799be82b1..3e639279d9e 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -483,6 +483,11 @@ GLIBCXX_CHECK_FILESYSTEM_DEPS
 
 # For Networking TS.
 AC_CHECK_HEADERS([fcntl.h sys/ioctl.h sys/socket.h sys/uio.h poll.h netdb.h arpa/inet.h netinet/in.h netinet/tcp.h])
+AC_CHECK_DECL(F_GETFL,,,[#include <fcntl.h>])
+AC_CHECK_DECL(F_SETFL,,,[#include <fcntl.h>])
+if test "$ac_cv_have_decl_F_GETFL$ac_cv_have_decl_F_SETFL" = yesyes ; then
+  AC_CHECK_DECL(O_NONBLOCK,,,[#include <fcntl.h>])
+fi
 
 # For Transactional Memory TS
 GLIBCXX_CHECK_SIZE_T_MANGLING
diff --git a/libstdc++-v3/include/experimental/internet b/libstdc++-v3/include/experimental/internet
index f6d6ef34504..6ce070ae775 100644
--- a/libstdc++-v3/include/experimental/internet
+++ b/libstdc++-v3/include/experimental/internet
@@ -61,6 +61,10 @@
 # include <netdb.h>		// getaddrinfo etc.
 #endif
 
+#if defined _WIN32 && __has_include(<ws2tcpip.h>)
+# include <ws2tcpip.h>
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -263,7 +267,11 @@ namespace ip
     _S_ntoh_32(uint32_t __n) { return __builtin_bswap32(__n); }
 #endif
 
+#ifdef _GLIBCXX_HAVE_ARPA_INET_H
     in_addr_t _M_addr; // network byte order
+#else
+    uint32_t _M_addr;
+#endif
   };
 
   /// An IPv6 address.
@@ -705,7 +713,7 @@ namespace ip
   inline address_v4
   make_address_v4(string_view __str, error_code& __ec) noexcept
   {
-    char __buf[INET_ADDRSTRLEN];
+    char __buf[16]; // INET_ADDRSTRLEN isn't defined on Windows
     auto __len = __str.copy(__buf, sizeof(__buf));
     if (__len == sizeof(__buf))
       {
@@ -1686,9 +1694,15 @@ namespace ip
 #ifdef AI_NUMERICSERV
     static constexpr flags numeric_service	= (flags)AI_NUMERICSERV;
 #endif
+#ifdef AI_V4MAPPED
     static constexpr flags v4_mapped		= (flags)AI_V4MAPPED;
+#endif
+#ifdef AI_ALL
     static constexpr flags all_matching		= (flags)AI_ALL;
+#endif
+#ifdef AI_ADDRCONFIG
     static constexpr flags address_configured	= (flags)AI_ADDRCONFIG;
+#endif
 
     friend constexpr flags
     operator&(flags __f1, flags __f2) noexcept
diff --git a/libstdc++-v3/include/experimental/socket b/libstdc++-v3/include/experimental/socket
index 9db4a245ccf..375e4e24974 100644
--- a/libstdc++-v3/include/experimental/socket
+++ b/libstdc++-v3/include/experimental/socket
@@ -293,11 +293,14 @@ inline namespace v1
       static const int _S_level = SOL_SOCKET;
       static const int _S_name = SO_SNDLOWAT;
     };
+#endif // HAVE_SYS_SOCKET_H
 
     enum shutdown_type : int { };
+#if defined SHUT_RD && defined SHUT_WR && defined SHUT_RDWR
     static constexpr shutdown_type shutdown_receive = (shutdown_type)SHUT_RD;
     static constexpr shutdown_type shutdown_send    = (shutdown_type)SHUT_WR;
     static constexpr shutdown_type shutdown_both    = (shutdown_type)SHUT_RDWR;
+#endif
 
     enum wait_type : int { };
 #ifdef _GLIBCXX_HAVE_POLL_H
@@ -311,14 +314,20 @@ inline namespace v1
 #endif
 
     enum message_flags : int { };
+#if defined MSG_PEEK && defined MSG_OOB && defined MSG_DONTROUTE
     static constexpr message_flags message_peek
       = (message_flags)MSG_PEEK;
     static constexpr message_flags message_out_of_band
       = (message_flags)MSG_OOB;
     static constexpr message_flags message_do_not_route
       = (message_flags)MSG_DONTROUTE;
+#endif
 
-    static const int max_listen_connections = SOMAXCONN;
+#ifdef SOMAXCONN
+    static constexpr int max_listen_connections = SOMAXCONN;
+#else
+    static constexpr int max_listen_connections = 4;
+#endif
 
     // message_flags bitmask operations are defined as hidden friends.
 
@@ -350,6 +359,7 @@ inline namespace v1
     operator^=(message_flags& __f1, message_flags __f2) noexcept
     { return __f1 = (__f1 ^ __f2); }
 
+#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
   protected:
     struct __msg_hdr : ::msghdr
     {
@@ -483,7 +493,7 @@ inline namespace v1
     void
     native_non_blocking(bool __mode, error_code& __ec)
     {
-#ifdef _GLIBCXX_HAVE_FCNTL_H
+#if defined _GLIBCXX_HAVE_FCNTL_H && defined _GLIBCXX_HAVE_DECL_O_NONBLOCK
       int __flags = ::fcntl(_M_sockfd, F_GETFL, 0);
       if (__flags >= 0)
 	{
@@ -508,7 +518,7 @@ inline namespace v1
     bool
     native_non_blocking() const
     {
-#ifdef _GLIBCXX_HAVE_FCNTL_H
+#if defined _GLIBCXX_HAVE_FCNTL_H && defined _GLIBCXX_HAVE_DECL_O_NONBLOCK
       if (_M_bits.native_non_blocking == -1)
 	{
 	  const int __flags = ::fcntl(_M_sockfd, F_GETFL, 0);
@@ -714,7 +724,9 @@ inline namespace v1
 	  {
 	    error_code __ec;
 	    cancel(__ec);
+#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
 	    set_option(socket_base::linger{false, chrono::seconds{}}, __ec);
+#endif
 	    ::close(_M_sockfd);
 	  }
       }
@@ -1892,11 +1904,13 @@ inline namespace v1
       { open(__protocol); }
 
       basic_socket_acceptor(io_context& __ctx, const endpoint_type& __endpoint,
-			    bool __reuse_addr = true)
+			    [[__maybe_unused__]] bool __reuse_addr = true)
       : basic_socket_acceptor(__ctx, __endpoint.protocol())
       {
+#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
 	if (__reuse_addr)
 	  set_option(reuse_address(true));
+#endif
 	bind(__endpoint);
 	listen();
       }
diff --git a/libstdc++-v3/testsuite/experimental/net/internet/resolver/base.cc b/libstdc++-v3/testsuite/experimental/net/internet/resolver/base.cc
index 4c36b03ebcc..e2167b72c0d 100644
--- a/libstdc++-v3/testsuite/experimental/net/internet/resolver/base.cc
+++ b/libstdc++-v3/testsuite/experimental/net/internet/resolver/base.cc
@@ -32,9 +32,15 @@ static_assert( __gnu_test::test_bitmask_values({
 #ifdef AI_NUMERICSERV
   resolver_base::numeric_service,
 #endif
+#ifdef AI_V4MAPPED
   resolver_base::v4_mapped,
+#endif
+#ifdef AI_ALL
   resolver_base::all_matching,
+#endif
+#ifdef AI_ADDRCONFIG
   resolver_base::address_configured
+#endif
 }), "each bitmask element is distinct" );
 
 static_assert( ! std::is_default_constructible<resolver_base>(), "protected" );
diff --git a/libstdc++-v3/testsuite/experimental/net/socket/basic_socket.cc b/libstdc++-v3/testsuite/experimental/net/socket/basic_socket.cc
index 7fe3ec04521..6cf11f6c305 100644
--- a/libstdc++-v3/testsuite/experimental/net/socket/basic_socket.cc
+++ b/libstdc++-v3/testsuite/experimental/net/socket/basic_socket.cc
@@ -22,10 +22,6 @@
 namespace net = std::experimental::net;
 using namespace std;
 
-namespace test
-{
-}
-
 void
 test01(net::io_context& io)
 {
@@ -113,8 +109,10 @@ test01(net::io_context& io)
   s.bind(e);
   s.bind(e, ec);
 
+#ifdef SHUT_RDWR
   s.shutdown(net::socket_base::shutdown_both);
   s.shutdown(net::socket_base::shutdown_both, ec);
+#endif
 
   e = s.local_endpoint();
   e = s.local_endpoint(ec);
diff --git a/libstdc++-v3/testsuite/experimental/net/socket/socket_base.cc b/libstdc++-v3/testsuite/experimental/net/socket/socket_base.cc
index f957b6c92f6..67da9dbf113 100644
--- a/libstdc++-v3/testsuite/experimental/net/socket/socket_base.cc
+++ b/libstdc++-v3/testsuite/experimental/net/socket/socket_base.cc
@@ -174,24 +174,28 @@ void test_option_types()
 
 void test_constants()
 {
-#if __has_include(<sys/socket.h>)
   static_assert( is_enum<S::shutdown_type>::value, "" );
+#if __has_include(<sys/socket.h>) && defined SHUT_RDWR
   static_assert( S::shutdown_receive != S::shutdown_send, "" );
   static_assert( S::shutdown_receive != S::shutdown_both, "" );
   static_assert( S::shutdown_send != S::shutdown_both, "" );
+#endif
 
   static_assert( is_enum<S::wait_type>::value, "" );
+#if __has_include(<poll.h>) && defined POLLIN
   static_assert( S::wait_read != S::wait_write, "");
   static_assert( S::wait_read != S::wait_error, "");
   static_assert( S::wait_write != S::wait_error, "");
+#endif
 
+  static_assert( is_enum<S::message_flags>::value, "" );
+#if __has_include(<sys/socket.h>) && defined MSG_OOB
   static_assert( __gnu_test::test_bitmask_values(
 	{S::message_peek, S::message_out_of_band, S::message_do_not_route}
 	), "each bitmask element is distinct" );
-
-  auto m = &S::max_listen_connections;
-  static_assert( is_same<decltype(m), const int*>::value, "" );
 #endif
+
+  static_assert( is_same<decltype(S::max_listen_connections), const int>::value, "" );
 }
 
 int main()


More information about the Libstdc++-cvs mailing list