Update of /cvsroot/boost/boost/boost/asio/detail
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv28503/detail
Modified Files:
socket_ops.hpp
Log Message:
Work around mysterious Borland C++ bug that prevents getsockopt and
setsockopt from working correctly.
Index: socket_ops.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/asio/detail/socket_ops.hpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- socket_ops.hpp 20 May 2007 00:28:13 -0000 1.13
+++ socket_ops.hpp 21 May 2007 13:05:06 -0000 1.14
@@ -325,11 +325,29 @@
return -1;
}
+#if defined(__BORLANDC__)
+ // Mysteriously, using the getsockopt and setsockopt functions directly with
+ // Borland C++ results in incorrect values being set and read. The bug can be
+ // worked around by using function addresses resolved with GetProcAddress.
+ if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
+ {
+ typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int);
+ if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt"))
+ {
+ clear_error(ec);
+ return error_wrapper(sso(s, level, optname,
+ reinterpret_cast<const char*>(optval),
+ static_cast<int>(optlen)), ec);
+ }
+ }
+ ec = boost::asio::error::fault;
+ return -1;
+#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
return error_wrapper(::setsockopt(s, level, optname,
reinterpret_cast<const char*>(optval), static_cast<int>(optlen)), ec);
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ clear_error(ec);
return error_wrapper(::setsockopt(s, level, optname, optval,
static_cast<socklen_t>(optlen)), ec);
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -344,8 +362,38 @@
return -1;
}
+#if defined(__BORLANDC__)
+ // Mysteriously, using the getsockopt and setsockopt functions directly with
+ // Borland C++ results in incorrect values being set and read. The bug can be
+ // worked around by using function addresses resolved with GetProcAddress.
+ if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
+ {
+ typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*);
+ if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt"))
+ {
+ clear_error(ec);
+ int tmp_optlen = static_cast<int>(*optlen);
+ int result = error_wrapper(gso(s, level, optname,
+ reinterpret_cast<char*>(optval), &tmp_optlen), ec);
+ *optlen = static_cast<size_t>(tmp_optlen);
+ if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
+ && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
+ {
+ // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are
+ // only supported on Windows Vista and later. To simplify program logic
+ // we will fake success of getting this option and specify that the
+ // value is non-zero (i.e. true). This corresponds to the behavior of
+ // IPv6 sockets on Windows platforms pre-Vista.
+ *static_cast<DWORD*>(optval) = 1;
+ clear_error(ec);
+ }
+ return result;
+ }
+ }
+ ec = boost::asio::error::fault;
+ return -1;
+#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
int tmp_optlen = static_cast<int>(*optlen);
int result = error_wrapper(::getsockopt(s, level, optname,
reinterpret_cast<char*>(optval), &tmp_optlen), ec);
@@ -363,6 +411,7 @@
}
return result;
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ clear_error(ec);
socklen_t tmp_optlen = static_cast<socklen_t>(*optlen);
int result = error_wrapper(::getsockopt(s, level, optname,
optval, &tmp_optlen), ec);
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs