commit cd67d138ec6006d650d1ba96c8a1322b285723cd Author: Jonathan Wakely Date: Thu Aug 26 12:06:55 2021 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 libstdc++-v3/ChangeLog: PR libstdc++/100285 * configure.ac: Check for O_NONBLOCK. * configure: Regenerate. * include/experimental/internet: Include 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 --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index 9d70ae7b1d0..d29efa6cb5f 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -481,6 +481,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,[],[],[fcntl.h]) +AC_CHECK_DECL(F_SETFL,[],[],[fcntl.h]) +if [ "$ac_cv_have_decl_F_GETFL$ac_cv_have_decl_F_SETFL" = 11 ]; then + AC_CHECK_DECL(O_NONBLOCK,[],[],[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 // getaddrinfo etc. #endif +#if defined _WIN32 && __has_include() +# include +#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 6d1c114254a..94241649777 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(), "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() static_assert( is_enum::value, "" ); +#if __has_include() && 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::value, "" ); +#if __has_include() && 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::value, "" ); +#if __has_include() && 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::value, "" ); #endif + + static_assert( is_same::value, "" ); } int main()