From b9e5d3c2ef76d1c1bd1a12b86549c70b6660e9da Mon Sep 17 00:00:00 2001 From: Sergey Mitrofanov Date: Fri, 12 Apr 2024 21:48:29 +0300 Subject: [PATCH] Support detection of file descriptor blocking mode on Unixes --- groups/nts/ntsb/ntsb_datagramsocket.cpp | 5 + groups/nts/ntsb/ntsb_datagramsocket.h | 4 + groups/nts/ntsb/ntsb_listenersocket.cpp | 5 + groups/nts/ntsb/ntsb_listenersocket.h | 4 + groups/nts/ntsb/ntsb_streamsocket.cpp | 5 + groups/nts/ntsb/ntsb_streamsocket.h | 4 + groups/nts/ntsi/ntsi_datagramsocket.cpp | 7 ++ groups/nts/ntsi/ntsi_datagramsocket.h | 4 + groups/nts/ntsi/ntsi_listenersocket.cpp | 7 ++ groups/nts/ntsi/ntsi_listenersocket.h | 4 + groups/nts/ntsi/ntsi_streamsocket.cpp | 7 ++ groups/nts/ntsi/ntsi_streamsocket.h | 4 + groups/nts/ntsu/ntsu_socketoptionutil.cpp | 104 +++++++++++--------- groups/nts/ntsu/ntsu_socketoptionutil.h | 4 + groups/nts/ntsu/ntsu_socketoptionutil.t.cpp | 97 ++++++++++++++++++ 15 files changed, 221 insertions(+), 44 deletions(-) diff --git a/groups/nts/ntsb/ntsb_datagramsocket.cpp b/groups/nts/ntsb/ntsb_datagramsocket.cpp index 3b0360dd..a9d95dfe 100644 --- a/groups/nts/ntsb/ntsb_datagramsocket.cpp +++ b/groups/nts/ntsb/ntsb_datagramsocket.cpp @@ -204,6 +204,11 @@ ntsa::Error DatagramSocket::setBlocking(bool blocking) return ntsu::SocketOptionUtil::setBlocking(d_handle, blocking); } +ntsa::Error DatagramSocket::isBlocking(bool* blocking) const +{ + return ntsu::SocketOptionUtil::isBlocking(d_handle, blocking); +} + ntsa::Error DatagramSocket::setOption(const ntsa::SocketOption& option) { return ntsu::SocketOptionUtil::setOption(d_handle, option); diff --git a/groups/nts/ntsb/ntsb_datagramsocket.h b/groups/nts/ntsb/ntsb_datagramsocket.h index 1cdcc326..7aef8ffc 100644 --- a/groups/nts/ntsb/ntsb_datagramsocket.h +++ b/groups/nts/ntsb/ntsb_datagramsocket.h @@ -190,6 +190,10 @@ class DatagramSocket : public ntsi::DatagramSocket /// according to the specified 'blocking' flag. Return the error. ntsa::Error setBlocking(bool blocking) BSLS_KEYWORD_OVERRIDE; + /// Request the kernel if the socket is in a blocking mode and load the + /// result in the specified 'blocking' Return the error. + ntsa::Error isBlocking(bool* blocking) const BSLS_KEYWORD_OVERRIDE; + /// Set the specified 'option' for this socket. Return the error. ntsa::Error setOption(const ntsa::SocketOption& option) BSLS_KEYWORD_OVERRIDE; diff --git a/groups/nts/ntsb/ntsb_listenersocket.cpp b/groups/nts/ntsb/ntsb_listenersocket.cpp index ae1eeefa..a32c01a8 100644 --- a/groups/nts/ntsb/ntsb_listenersocket.cpp +++ b/groups/nts/ntsb/ntsb_listenersocket.cpp @@ -188,6 +188,11 @@ ntsa::Error ListenerSocket::setBlocking(bool blocking) return ntsu::SocketOptionUtil::setBlocking(d_handle, blocking); } +ntsa::Error ListenerSocket::isBlocking(bool* blocking) const +{ + return ntsu::SocketOptionUtil::isBlocking(d_handle, blocking); +} + ntsa::Error ListenerSocket::setOption(const ntsa::SocketOption& option) { return ntsu::SocketOptionUtil::setOption(d_handle, option); diff --git a/groups/nts/ntsb/ntsb_listenersocket.h b/groups/nts/ntsb/ntsb_listenersocket.h index 37cf6c76..cbaccad0 100644 --- a/groups/nts/ntsb/ntsb_listenersocket.h +++ b/groups/nts/ntsb/ntsb_listenersocket.h @@ -146,6 +146,10 @@ class ListenerSocket : public ntsi::ListenerSocket /// according to the specified 'blocking' flag. Return the error. ntsa::Error setBlocking(bool blocking) BSLS_KEYWORD_OVERRIDE; + /// Request the kernel if the socket is in a blocking mode and load the + /// result in the specified 'blocking' Return the error. + ntsa::Error isBlocking(bool* blocking) const BSLS_KEYWORD_OVERRIDE; + /// Set the specified 'option' for this socket. Return the error. ntsa::Error setOption(const ntsa::SocketOption& option) BSLS_KEYWORD_OVERRIDE; diff --git a/groups/nts/ntsb/ntsb_streamsocket.cpp b/groups/nts/ntsb/ntsb_streamsocket.cpp index 92f5e1d1..f9f7f30d 100644 --- a/groups/nts/ntsb/ntsb_streamsocket.cpp +++ b/groups/nts/ntsb/ntsb_streamsocket.cpp @@ -168,6 +168,11 @@ ntsa::Error StreamSocket::setBlocking(bool blocking) return ntsu::SocketOptionUtil::setBlocking(d_handle, blocking); } +ntsa::Error StreamSocket::isBlocking(bool* blocking) const +{ + return ntsu::SocketOptionUtil::isBlocking(d_handle, blocking); +} + ntsa::Error StreamSocket::setOption(const ntsa::SocketOption& option) { return ntsu::SocketOptionUtil::setOption(d_handle, option); diff --git a/groups/nts/ntsb/ntsb_streamsocket.h b/groups/nts/ntsb/ntsb_streamsocket.h index 502b7602..3ee7808b 100644 --- a/groups/nts/ntsb/ntsb_streamsocket.h +++ b/groups/nts/ntsb/ntsb_streamsocket.h @@ -156,6 +156,10 @@ class StreamSocket : public ntsi::StreamSocket /// according to the specified 'blocking' flag. Return the error. ntsa::Error setBlocking(bool blocking) BSLS_KEYWORD_OVERRIDE; + /// Request the kernel if the socket is in a blocking mode and load the + /// result in the specified 'blocking' Return the error. + ntsa::Error isBlocking(bool* blocking) const BSLS_KEYWORD_OVERRIDE; + /// Set the specified 'option' for this socket. Return the error. ntsa::Error setOption(const ntsa::SocketOption& option) BSLS_KEYWORD_OVERRIDE; diff --git a/groups/nts/ntsi/ntsi_datagramsocket.cpp b/groups/nts/ntsi/ntsi_datagramsocket.cpp index f3d67ceb..3b6e523e 100644 --- a/groups/nts/ntsi/ntsi_datagramsocket.cpp +++ b/groups/nts/ntsi/ntsi_datagramsocket.cpp @@ -182,6 +182,13 @@ ntsa::Error DatagramSocket::setBlocking(bool blocking) return ntsa::Error(ntsa::Error::e_NOT_IMPLEMENTED); } +ntsa::Error DatagramSocket::isBlocking(bool* blocking) const +{ + NTSCFG_WARNING_UNUSED(blocking); + + return ntsa::Error(ntsa::Error::e_NOT_IMPLEMENTED); +} + ntsa::Error DatagramSocket::setOption(const ntsa::SocketOption& option) { NTSCFG_WARNING_UNUSED(option); diff --git a/groups/nts/ntsi/ntsi_datagramsocket.h b/groups/nts/ntsi/ntsi_datagramsocket.h index e984b1f0..4648c63e 100644 --- a/groups/nts/ntsi/ntsi_datagramsocket.h +++ b/groups/nts/ntsi/ntsi_datagramsocket.h @@ -562,6 +562,10 @@ class DatagramSocket : public ntsi::Channel /// according to the specified 'blocking' flag. Return the error. virtual ntsa::Error setBlocking(bool blocking); + /// If the socket is in a blocking mode then load true in the specified + /// 'blocking', otherwise load false. Return the error. + virtual ntsa::Error isBlocking(bool* blocking) const; + /// Set the specified 'option' for this socket. Return the error. virtual ntsa::Error setOption(const ntsa::SocketOption& option); diff --git a/groups/nts/ntsi/ntsi_listenersocket.cpp b/groups/nts/ntsi/ntsi_listenersocket.cpp index 17c08194..474f755b 100644 --- a/groups/nts/ntsi/ntsi_listenersocket.cpp +++ b/groups/nts/ntsi/ntsi_listenersocket.cpp @@ -115,6 +115,13 @@ ntsa::Error ListenerSocket::setBlocking(bool blocking) return ntsa::Error(ntsa::Error::e_NOT_IMPLEMENTED); } +ntsa::Error ListenerSocket::isBlocking(bool* blocking) const +{ + NTSCFG_WARNING_UNUSED(blocking); + + return ntsa::Error(ntsa::Error::e_NOT_IMPLEMENTED); +} + ntsa::Error ListenerSocket::setOption(const ntsa::SocketOption& option) { NTSCFG_WARNING_UNUSED(option); diff --git a/groups/nts/ntsi/ntsi_listenersocket.h b/groups/nts/ntsi/ntsi_listenersocket.h index f511d87c..4b2f11d6 100644 --- a/groups/nts/ntsi/ntsi_listenersocket.h +++ b/groups/nts/ntsi/ntsi_listenersocket.h @@ -176,6 +176,10 @@ class ListenerSocket : public ntsi::Descriptor /// according to the specified 'blocking' flag. Return the error. virtual ntsa::Error setBlocking(bool blocking); + /// If the socket is in a blocking mode then load true in the specified + /// 'blocking', otherwise load false. Return the error. + virtual ntsa::Error isBlocking(bool* blocking) const; + /// Set the specified 'option' for this socket. Return the error. virtual ntsa::Error setOption(const ntsa::SocketOption& option); diff --git a/groups/nts/ntsi/ntsi_streamsocket.cpp b/groups/nts/ntsi/ntsi_streamsocket.cpp index ba04444c..964730e3 100644 --- a/groups/nts/ntsi/ntsi_streamsocket.cpp +++ b/groups/nts/ntsi/ntsi_streamsocket.cpp @@ -140,6 +140,13 @@ ntsa::Error StreamSocket::setBlocking(bool blocking) return ntsa::Error(ntsa::Error::e_NOT_IMPLEMENTED); } +ntsa::Error StreamSocket::isBlocking(bool* blocking) const +{ + NTSCFG_WARNING_UNUSED(blocking); + + return ntsa::Error(ntsa::Error::e_NOT_IMPLEMENTED); +} + ntsa::Error StreamSocket::setOption(const ntsa::SocketOption& option) { NTSCFG_WARNING_UNUSED(option); diff --git a/groups/nts/ntsi/ntsi_streamsocket.h b/groups/nts/ntsi/ntsi_streamsocket.h index 95796927..f64baeac 100644 --- a/groups/nts/ntsi/ntsi_streamsocket.h +++ b/groups/nts/ntsi/ntsi_streamsocket.h @@ -332,6 +332,10 @@ class StreamSocket : public ntsi::Channel /// according to the specified 'blocking' flag. Return the error. virtual ntsa::Error setBlocking(bool blocking); + /// If the socket is in a blocking mode then load true in the specified + /// 'blocking', otherwise load false. Return the error. + virtual ntsa::Error isBlocking(bool* blocking) const; + /// Set the specified 'option' for this socket. Return the error. virtual ntsa::Error setOption(const ntsa::SocketOption& option); diff --git a/groups/nts/ntsu/ntsu_socketoptionutil.cpp b/groups/nts/ntsu/ntsu_socketoptionutil.cpp index 55cffbb3..87f9f302 100644 --- a/groups/nts/ntsu/ntsu_socketoptionutil.cpp +++ b/groups/nts/ntsu/ntsu_socketoptionutil.cpp @@ -20,8 +20,8 @@ BSLS_IDENT_RCSID(ntsu_socketoptionutil_cpp, "$Id$ $CSID$") #include #include -#include #include +#include #include #include @@ -348,6 +348,18 @@ ntsa::Error SocketOptionUtil::setBlocking(ntsa::Handle socket, bool blocking) return ntsa::Error(); } +ntsa::Error SocketOptionUtil::isBlocking(ntsa::Handle socket, bool* blocking) +{ + const int flags = fcntl(socket, F_GETFL, 0); + if (flags < 0) { + return ntsa::Error(errno); + } + + *blocking = ((flags & O_NONBLOCK) == 0); + + return ntsa::Error(); +} + ntsa::Error SocketOptionUtil::setKeepAlive(ntsa::Handle socket, bool keepAlive) { int optionValue = static_cast(keepAlive); @@ -438,9 +450,8 @@ ntsa::Error SocketOptionUtil::setReuseAddress(ntsa::Handle socket, return ntsa::Error(); } -ntsa::Error SocketOptionUtil::setTimestampIncomingData( - ntsa::Handle socket, - bool timestampFlag) +ntsa::Error SocketOptionUtil::setTimestampIncomingData(ntsa::Handle socket, + bool timestampFlag) { #if defined(BSLS_PLATFORM_OS_LINUX) @@ -454,15 +465,15 @@ ntsa::Error SocketOptionUtil::setTimestampIncomingData( int optionValue = 0; socklen_t optionLength = static_cast(sizeof(optionValue)); - rc = getsockopt(socket, - SOL_SOCKET, - ntsu::TimestampUtil::e_SO_TIMESTAMPING, - &optionValue, + rc = getsockopt(socket, + SOL_SOCKET, + ntsu::TimestampUtil::e_SO_TIMESTAMPING, + &optionValue, &optionLength); if (rc != 0) { return ntsa::Error(errno); } - + if (optionLength != static_cast(sizeof(optionValue))) { return ntsa::Error(ntsa::Error::e_INVALID); } @@ -474,8 +485,8 @@ ntsa::Error SocketOptionUtil::setTimestampIncomingData( } else { optionValue &= ~ntsu::TimestampUtil::e_SOF_TIMESTAMPING_RX_GENERATION; - if ((optionValue & - ntsu::TimestampUtil::e_SOF_TIMESTAMPING_TX_GENERATION) == 0) + if ((optionValue & + ntsu::TimestampUtil::e_SOF_TIMESTAMPING_TX_GENERATION) == 0) { optionValue &= ~ntsu::TimestampUtil::e_SOF_TIMESTAMPING_REPORTING; optionValue &= ~ntsu::TimestampUtil::e_SOF_TIMESTAMPING_OPTIONS; @@ -484,7 +495,7 @@ ntsa::Error SocketOptionUtil::setTimestampIncomingData( #if NTSU_SOCKETOPTIONUTIL_TIMESTAMPING_SAFE - optionValue = ntsu::TimestampUtil::removeUnsupported(optionValue); + optionValue = ntsu::TimestampUtil::removeUnsupported(optionValue); #endif @@ -525,15 +536,15 @@ ntsa::Error SocketOptionUtil::setTimestampOutgoingData(ntsa::Handle socket, int optionValue = 0; socklen_t optionLength = static_cast(sizeof(optionValue)); - rc = getsockopt(socket, - SOL_SOCKET, - ntsu::TimestampUtil::e_SO_TIMESTAMPING, - &optionValue, + rc = getsockopt(socket, + SOL_SOCKET, + ntsu::TimestampUtil::e_SO_TIMESTAMPING, + &optionValue, &optionLength); if (rc != 0) { return ntsa::Error(errno); } - + if (optionLength != static_cast(sizeof(optionValue))) { return ntsa::Error(ntsa::Error::e_INVALID); } @@ -545,8 +556,8 @@ ntsa::Error SocketOptionUtil::setTimestampOutgoingData(ntsa::Handle socket, } else { optionValue &= ~ntsu::TimestampUtil::e_SOF_TIMESTAMPING_TX_GENERATION; - if ((optionValue & - ntsu::TimestampUtil::e_SOF_TIMESTAMPING_RX_GENERATION) == 0) + if ((optionValue & + ntsu::TimestampUtil::e_SOF_TIMESTAMPING_RX_GENERATION) == 0) { optionValue &= ~ntsu::TimestampUtil::e_SOF_TIMESTAMPING_REPORTING; optionValue &= ~ntsu::TimestampUtil::e_SOF_TIMESTAMPING_OPTIONS; @@ -555,7 +566,7 @@ ntsa::Error SocketOptionUtil::setTimestampOutgoingData(ntsa::Handle socket, #if NTSU_SOCKETOPTIONUTIL_TIMESTAMPING_SAFE - optionValue = ntsu::TimestampUtil::removeUnsupported(optionValue); + optionValue = ntsu::TimestampUtil::removeUnsupported(optionValue); #endif @@ -1102,10 +1113,10 @@ ntsa::Error SocketOptionUtil::getTimestampIncomingData(bool* timestampFlag, int optionValue = 0; socklen_t optionLength = static_cast(sizeof(optionValue)); - rc = getsockopt(socket, - SOL_SOCKET, - ntsu::TimestampUtil::e_SO_TIMESTAMPING, - &optionValue, + rc = getsockopt(socket, + SOL_SOCKET, + ntsu::TimestampUtil::e_SO_TIMESTAMPING, + &optionValue, &optionLength); if (rc != 0) { @@ -1116,8 +1127,8 @@ ntsa::Error SocketOptionUtil::getTimestampIncomingData(bool* timestampFlag, return ntsa::Error(ntsa::Error::e_INVALID); } - if ((optionValue & - ntsu::TimestampUtil::e_SOF_TIMESTAMPING_RX_GENERATION) != 0) + if ((optionValue & + ntsu::TimestampUtil::e_SOF_TIMESTAMPING_RX_GENERATION) != 0) { *timestampFlag = true; } @@ -1149,10 +1160,10 @@ ntsa::Error SocketOptionUtil::getTimestampOutgoingData(bool* timestampFlag, int optionValue = 0; socklen_t optionLength = static_cast(sizeof(optionValue)); - rc = getsockopt(socket, - SOL_SOCKET, - ntsu::TimestampUtil::e_SO_TIMESTAMPING, - &optionValue, + rc = getsockopt(socket, + SOL_SOCKET, + ntsu::TimestampUtil::e_SO_TIMESTAMPING, + &optionValue, &optionLength); if (rc != 0) { @@ -1163,8 +1174,8 @@ ntsa::Error SocketOptionUtil::getTimestampOutgoingData(bool* timestampFlag, return ntsa::Error(ntsa::Error::e_INVALID); } - if ((optionValue & - ntsu::TimestampUtil::e_SOF_TIMESTAMPING_TX_GENERATION) != 0) + if ((optionValue & + ntsu::TimestampUtil::e_SOF_TIMESTAMPING_TX_GENERATION) != 0) { *timestampFlag = true; } @@ -1829,7 +1840,7 @@ bool SocketOptionUtil::supportsNotifications(ntsa::Handle socket) // Notifications are not supported on local sockets. bool isLocalFlag = false; - error = ntsu::SocketOptionUtil::isLocal(&isLocalFlag, socket); + error = ntsu::SocketOptionUtil::isLocal(&isLocalFlag, socket); if (error) { return false; } @@ -1845,7 +1856,7 @@ bool SocketOptionUtil::supportsNotifications(ntsa::Handle socket) int minor = 0; int patch = 0; int build = 0; - + rc = ntsscm::Version::systemVersion(&major, &minor, &patch, &build); if (rc != 0) { return false; @@ -1875,7 +1886,7 @@ bool SocketOptionUtil::supportsTimestamping(ntsa::Handle socket) // Notifications are not supported on local sockets. bool isLocalFlag = false; - error = ntsu::SocketOptionUtil::isLocal(&isLocalFlag, socket); + error = ntsu::SocketOptionUtil::isLocal(&isLocalFlag, socket); if (error) { return false; } @@ -1891,7 +1902,7 @@ bool SocketOptionUtil::supportsTimestamping(ntsa::Handle socket) int minor = 0; int patch = 0; int build = 0; - + rc = ntsscm::Version::systemVersion(&major, &minor, &patch, &build); if (rc != 0) { return false; @@ -1919,7 +1930,7 @@ bool SocketOptionUtil::supportsZeroCopy(ntsa::Handle socket) int rc; bool isLocalFlag = false; - error = ntsu::SocketOptionUtil::isLocal(&isLocalFlag, socket); + error = ntsu::SocketOptionUtil::isLocal(&isLocalFlag, socket); if (error) { return false; } @@ -1932,7 +1943,7 @@ bool SocketOptionUtil::supportsZeroCopy(ntsa::Handle socket) int minor = 0; int patch = 0; int build = 0; - + rc = ntsscm::Version::systemVersion(&major, &minor, &patch, &build); if (rc != 0) { return false; @@ -1979,6 +1990,13 @@ ntsa::Error SocketOptionUtil::setBlocking(ntsa::Handle socket, bool blocking) return ntsa::Error(); } +ntsa::Error SocketOptionUtil::isBlocking(ntsa::Handle socket, bool* blocking) +{ + NTSCFG_WARNING_UNUSED(socket); + NTSCFG_WARNING_UNUSED(blocking); + return ntsa::Error(ntsa::Error::e_NOT_IMPLEMENTED); +} + ntsa::Error SocketOptionUtil::setKeepAlive(ntsa::Handle socket, bool keepAlive) { BOOL optionValue = static_cast(keepAlive); @@ -2048,9 +2066,8 @@ ntsa::Error SocketOptionUtil::setReuseAddress(ntsa::Handle socket, return ntsa::Error(); } -ntsa::Error SocketOptionUtil::setTimestampIncomingData( - ntsa::Handle socket, - bool timestampFlag) +ntsa::Error SocketOptionUtil::setTimestampIncomingData(ntsa::Handle socket, + bool timestampFlag) { NTSCFG_WARNING_UNUSED(socket); NTSCFG_WARNING_UNUSED(timestampFlag); @@ -2058,9 +2075,8 @@ ntsa::Error SocketOptionUtil::setTimestampIncomingData( return ntsa::Error(ntsa::Error::e_NOT_IMPLEMENTED); } -ntsa::Error SocketOptionUtil::setTimestampOutgoingData( - ntsa::Handle socket, - bool timestampFlag) +ntsa::Error SocketOptionUtil::setTimestampOutgoingData(ntsa::Handle socket, + bool timestampFlag) { NTSCFG_WARNING_UNUSED(socket); NTSCFG_WARNING_UNUSED(timestampFlag); diff --git a/groups/nts/ntsu/ntsu_socketoptionutil.h b/groups/nts/ntsu/ntsu_socketoptionutil.h index d1b1d3fc..961b9a90 100644 --- a/groups/nts/ntsu/ntsu_socketoptionutil.h +++ b/groups/nts/ntsu/ntsu_socketoptionutil.h @@ -52,6 +52,10 @@ struct SocketOptionUtil { /// according to the specified 'blocking' flag. Return the error. static ntsa::Error setBlocking(ntsa::Handle socket, bool blocking); + /// If the specified 'socket' is in a blocking mode then load true in the + /// specified 'blocking', otherwise load false. Return the error. + static ntsa::Error isBlocking(ntsa::Handle handle, bool* blocking); + /// Set the option for the specified 'socket' that controls automatic /// periodic transmission of TCP keep-alive packets according to the /// specified 'keepAlive' flag. Return the error. diff --git a/groups/nts/ntsu/ntsu_socketoptionutil.t.cpp b/groups/nts/ntsu/ntsu_socketoptionutil.t.cpp index d9f29cc4..9c0cc2b7 100644 --- a/groups/nts/ntsu/ntsu_socketoptionutil.t.cpp +++ b/groups/nts/ntsu/ntsu_socketoptionutil.t.cpp @@ -1871,6 +1871,102 @@ NTSCFG_TEST_CASE(7) } } +NTSCFG_TEST_CASE(8) +{ + // Concern: test isLocal + + ntsa::Error error; + + const ntsa::Transport::Value SOCKET_TYPES[] = { + ntsa::Transport::e_TCP_IPV4_STREAM, + ntsa::Transport::e_TCP_IPV6_STREAM, +#if !defined(BSLS_PLATFORM_OS_WINDOWS) + ntsa::Transport::e_LOCAL_STREAM, +#endif + ntsa::Transport::e_UDP_IPV4_DATAGRAM, + ntsa::Transport::e_UDP_IPV6_DATAGRAM, +#if !defined(BSLS_PLATFORM_OS_WINDOWS) + ntsa::Transport::e_LOCAL_DATAGRAM, +#endif + }; + + for (bsl::size_t socketTypeIndex = 0; + socketTypeIndex < sizeof(SOCKET_TYPES) / sizeof(SOCKET_TYPES[0]); + ++socketTypeIndex) + { + ntsa::Transport::Value transport = SOCKET_TYPES[socketTypeIndex]; + + if (transport == ntsa::Transport::e_TCP_IPV4_STREAM || + transport == ntsa::Transport::e_UDP_IPV4_DATAGRAM) + { + if (!ntsu::AdapterUtil::supportsIpv4()) { + continue; + } + } + + if (transport == ntsa::Transport::e_TCP_IPV6_STREAM || + transport == ntsa::Transport::e_UDP_IPV6_DATAGRAM) + { + if (!ntsu::AdapterUtil::supportsIpv6()) { + continue; + } + } + + NTSCFG_TEST_LOG_WARN << "Testing " << transport << NTSCFG_TEST_LOG_END; + + ntsa::Handle socket; + { + const ntsa::Error error = ntsu::SocketUtil::create(&socket, transport); + NTSCFG_TEST_OK(error); + } + + { + const ntsa::Error error = ntsu::SocketOptionUtil::setBlocking(socket, false); + NTSCFG_TEST_OK(error); + } + { + bool blocking = true; + const ntsa::Error error = ntsu::SocketOptionUtil::isBlocking(socket, &blocking); +#if !defined(BSLS_PLATFORM_OS_WINDOWS) + NTSCFG_TEST_OK(error); + NTSCFG_TEST_FALSE(blocking); +#else + NTSCFG_TEST_ERROR(error, ntsa::Error::e_NOT_IMPLEMENTED); +#endif + } + { + const ntsa::Error error = ntsu::SocketOptionUtil::setBlocking(socket, true); + NTSCFG_TEST_OK(error); + } + { + bool blocking = false; + const ntsa::Error error = ntsu::SocketOptionUtil::isBlocking(socket, &blocking); +#if !defined(BSLS_PLATFORM_OS_WINDOWS) + NTSCFG_TEST_OK(error); + NTSCFG_TEST_TRUE(blocking); +#else + NTSCFG_TEST_ERROR(error, ntsa::Error::e_NOT_IMPLEMENTED); +#endif + } + { + const ntsa::Error error = ntsu::SocketOptionUtil::setBlocking(socket, false); + NTSCFG_TEST_OK(error); + } + { + bool blocking = true; + const ntsa::Error error = ntsu::SocketOptionUtil::isBlocking(socket, &blocking); +#if !defined(BSLS_PLATFORM_OS_WINDOWS) + NTSCFG_TEST_OK(error); + NTSCFG_TEST_FALSE(blocking); +#else + NTSCFG_TEST_ERROR(error, ntsa::Error::e_NOT_IMPLEMENTED); +#endif + } + } + + +} + NTSCFG_TEST_DRIVER { NTSCFG_TEST_REGISTER(1); @@ -1880,5 +1976,6 @@ NTSCFG_TEST_DRIVER NTSCFG_TEST_REGISTER(5); NTSCFG_TEST_REGISTER(6); NTSCFG_TEST_REGISTER(7); + NTSCFG_TEST_REGISTER(8); } NTSCFG_TEST_DRIVER_END;