in demo_example/asio/asio/detail/impl/socket_ops.ipp [1858:1933]
int setsockopt(socket_type s, state_type& state, int level, int optname,
const void* optval, std::size_t optlen, asio::error_code& ec)
{
if (s == invalid_socket)
{
ec = asio::error::bad_descriptor;
return socket_error_retval;
}
if (level == custom_socket_option_level && optname == always_fail_option)
{
ec = asio::error::invalid_argument;
return socket_error_retval;
}
if (level == custom_socket_option_level
&& optname == enable_connection_aborted_option)
{
if (optlen != sizeof(int))
{
ec = asio::error::invalid_argument;
return socket_error_retval;
}
if (*static_cast<const int*>(optval))
state |= enable_connection_aborted;
else
state &= ~enable_connection_aborted;
ec.assign(0, ec.category());
return 0;
}
if (level == SOL_SOCKET && optname == SO_LINGER)
state |= user_set_linger;
#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"))
{
int result = sso(s, level, optname,
reinterpret_cast<const char*>(optval),
static_cast<int>(optlen));
get_last_error(ec, result != 0);
return result;
}
}
ec = asio::error::fault;
return socket_error_retval;
#else // defined(__BORLANDC__)
int result = call_setsockopt(&msghdr::msg_namelen,
s, level, optname, optval, optlen);
get_last_error(ec, result != 0);
if (result == 0)
{
#if defined(__MACH__) && defined(__APPLE__) \
|| defined(__NetBSD__) || defined(__FreeBSD__) \
|| defined(__OpenBSD__) || defined(__QNX__)
// To implement portable behaviour for SO_REUSEADDR with UDP sockets we
// need to also set SO_REUSEPORT on BSD-based platforms.
if ((state & datagram_oriented)
&& level == SOL_SOCKET && optname == SO_REUSEADDR)
{
call_setsockopt(&msghdr::msg_namelen, s,
SOL_SOCKET, SO_REUSEPORT, optval, optlen);
}
#endif
}
return result;
#endif // defined(__BORLANDC__)
}