From 08c1e93fa36a49f49325a07fe91ff92c964c2b6c Mon Sep 17 00:00:00 2001 From: Chanho Park Date: Thu, 11 Dec 2014 18:55:56 +0900 Subject: Imported Upstream version 1.57.0 --- boost/asio/detail/impl/socket_ops.ipp | 749 ++++++++++++++++++++++++---------- 1 file changed, 541 insertions(+), 208 deletions(-) (limited to 'boost/asio/detail/impl/socket_ops.ipp') diff --git a/boost/asio/detail/impl/socket_ops.ipp b/boost/asio/detail/impl/socket_ops.ipp index 16e95366e6..fe7e894f53 100644 --- a/boost/asio/detail/impl/socket_ops.ipp +++ b/boost/asio/detail/impl/socket_ops.ipp @@ -2,7 +2,7 @@ // detail/impl/socket_ops.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -16,17 +16,31 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include -#include -#include + #include #include #include #include #include #include +#include #include #include +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) +# include +# include +# include +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) \ + || defined(__MACH__) && defined(__APPLE__) +# if defined(BOOST_ASIO_HAS_PTHREADS) +# include +# endif // defined(BOOST_ASIO_HAS_PTHREADS) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + // || defined(__MACH__) && defined(__APPLE__) + #include namespace boost { @@ -34,9 +48,11 @@ namespace asio { namespace detail { namespace socket_ops { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) struct msghdr { int msg_namelen; }; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) #if defined(__hpux) // HP-UX doesn't declare these functions extern "C", so they are declared again @@ -45,20 +61,24 @@ extern "C" char* if_indextoname(unsigned int, char*); extern "C" unsigned int if_nametoindex(const char*); #endif // defined(__hpux) +#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) + inline void clear_last_error() { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) WSASetLastError(0); #else errno = 0; #endif } +#if !defined(BOOST_ASIO_WINDOWS_RUNTIME) + template inline ReturnType error_wrapper(ReturnType return_value, boost::system::error_code& ec) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ec = boost::system::error_code(WSAGetLastError(), boost::asio::error::get_system_category()); #else @@ -293,11 +313,11 @@ int close(socket_type s, state_type& state, } clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::closesocket(s), ec); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::close(s), ec); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) if (result != 0 && (ec == boost::asio::error::would_block @@ -309,10 +329,10 @@ int close(socket_type s, state_type& state, // current OS where this behaviour is seen, Windows, says that the socket // remains open. Therefore we'll put the descriptor back into blocking // mode and have another attempt at closing it. -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ioctl_arg_type arg = 0; ::ioctlsocket(s, FIONBIO, &arg); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) # if defined(__SYMBIAN32__) int flags = ::fcntl(s, F_GETFL, 0); if (flags >= 0) @@ -321,15 +341,15 @@ int close(socket_type s, state_type& state, ioctl_arg_type arg = 0; ::ioctl(s, FIONBIO, &arg); # endif // defined(__SYMBIAN32__) -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) state &= ~non_blocking; clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::closesocket(s), ec); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::close(s), ec); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } } @@ -348,7 +368,7 @@ bool set_user_non_blocking(socket_type s, } clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ioctl_arg_type arg = (value ? 1 : 0); int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec); #elif defined(__SYMBIAN32__) @@ -401,7 +421,7 @@ bool set_internal_non_blocking(socket_type s, } clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ioctl_arg_type arg = (value ? 1 : 0); int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec); #elif defined(__SYMBIAN32__) @@ -501,8 +521,57 @@ void sync_connect(socket_type s, const socket_addr_type* addr, boost::asio::error::get_system_category()); } +#if defined(BOOST_ASIO_HAS_IOCP) + +void complete_iocp_connect(socket_type s, boost::system::error_code& ec) +{ + if (!ec) + { + // Need to set the SO_UPDATE_CONNECT_CONTEXT option so that getsockname + // and getpeername will work on the connected socket. + socket_ops::state_type state = 0; + const int so_update_connect_context = 0x7010; + socket_ops::setsockopt(s, state, SOL_SOCKET, + so_update_connect_context, 0, 0, ec); + } +} + +#endif // defined(BOOST_ASIO_HAS_IOCP) + bool non_blocking_connect(socket_type s, boost::system::error_code& ec) { + // Check if the connect operation has finished. This is required since we may + // get spurious readiness notifications from the reactor. +#if defined(BOOST_ASIO_WINDOWS) \ + || defined(__CYGWIN__) \ + || defined(__SYMBIAN32__) + fd_set write_fds; + FD_ZERO(&write_fds); + FD_SET(s, &write_fds); + fd_set except_fds; + FD_ZERO(&except_fds); + FD_SET(s, &except_fds); + timeval zero_timeout; + zero_timeout.tv_sec = 0; + zero_timeout.tv_usec = 0; + int ready = ::select(s + 1, 0, &write_fds, &except_fds, &zero_timeout); +#else // defined(BOOST_ASIO_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + pollfd fds; + fds.fd = s; + fds.events = POLLOUT; + fds.revents = 0; + int ready = ::poll(&fds, 1, 0); +#endif // defined(BOOST_ASIO_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + if (ready == 0) + { + // The asynchronous connect operation is still in progress. + return false; + } + // Get the error code from the connect operation. int connect_error = 0; size_t connect_error_len = sizeof(connect_error); @@ -524,7 +593,7 @@ bool non_blocking_connect(socket_type s, boost::system::error_code& ec) int socketpair(int af, int type, int protocol, socket_type sv[2], boost::system::error_code& ec) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) (void)(af); (void)(type); (void)(protocol); @@ -550,11 +619,11 @@ bool sockatmark(socket_type s, boost::system::error_code& ec) #if defined(SIOCATMARK) ioctl_arg_type value = 0; -# if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctlsocket(s, SIOCATMARK, &value), ec); -# else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctl(s, SIOCATMARK, &value), ec); -# endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) if (result == 0) ec = boost::system::error_code(); # if defined(ENOTTY) @@ -579,11 +648,11 @@ size_t available(socket_type s, boost::system::error_code& ec) } ioctl_arg_type value = 0; -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctlsocket(s, FIONREAD, &value), ec); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctl(s, FIONREAD, &value), ec); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) if (result == 0) ec = boost::system::error_code(); #if defined(ENOTTY) @@ -620,32 +689,32 @@ inline void init_buf_iov_base(T& base, void* addr) base = static_cast(addr); } -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) typedef WSABUF buf; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) typedef iovec buf; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) void init_buf(buf& b, void* data, size_t size) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) b.buf = static_cast(data); b.len = static_cast(size); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) init_buf_iov_base(b.iov_base, data); b.iov_len = size; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } void init_buf(buf& b, const void* data, size_t size) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) b.buf = static_cast(const_cast(data)); b.len = static_cast(size); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) init_buf_iov_base(b.iov_base, const_cast(data)); b.iov_len = size; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr) @@ -670,11 +739,11 @@ inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr) name = reinterpret_cast(const_cast(addr)); } -int recv(socket_type s, buf* bufs, size_t count, int flags, - boost::system::error_code& ec) +signed_size_type recv(socket_type s, buf* bufs, size_t count, + int flags, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Receive some data. DWORD recv_buf_count = static_cast(count); DWORD bytes_transferred = 0; @@ -689,15 +758,15 @@ int recv(socket_type s, buf* bufs, size_t count, int flags, return socket_error_retval; ec = boost::system::error_code(); return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); msg.msg_iov = bufs; - msg.msg_iovlen = count; - int result = error_wrapper(::recvmsg(s, &msg, flags), ec); + msg.msg_iovlen = static_cast(count); + signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); if (result >= 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_recv(socket_type s, state_type state, buf* bufs, @@ -720,7 +789,7 @@ size_t sync_recv(socket_type s, state_type state, buf* bufs, for (;;) { // Try to complete the operation without blocking. - int bytes = socket_ops::recv(s, bufs, count, flags, ec); + signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec); // Check if operation succeeded. if (bytes > 0) @@ -782,7 +851,7 @@ bool non_blocking_recv(socket_type s, for (;;) { // Read some data. - int bytes = socket_ops::recv(s, bufs, count, flags, ec); + signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec); // Check for end of stream. if (is_stream && bytes == 0) @@ -815,12 +884,12 @@ bool non_blocking_recv(socket_type s, #endif // defined(BOOST_ASIO_HAS_IOCP) -int recvfrom(socket_type s, buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, +signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, + int flags, socket_addr_type* addr, std::size_t* addrlen, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Receive some data. DWORD recv_buf_count = static_cast(count); DWORD bytes_transferred = 0; @@ -837,18 +906,18 @@ int recvfrom(socket_type s, buf* bufs, size_t count, int flags, return socket_error_retval; ec = boost::system::error_code(); return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = *addrlen; + msg.msg_namelen = static_cast(*addrlen); msg.msg_iov = bufs; - msg.msg_iovlen = count; - int result = error_wrapper(::recvmsg(s, &msg, flags), ec); + msg.msg_iovlen = static_cast(count); + signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); *addrlen = msg.msg_namelen; if (result >= 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, @@ -865,7 +934,8 @@ size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, for (;;) { // Try to complete the operation without blocking. - int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, ec); + signed_size_type bytes = socket_ops::recvfrom( + s, bufs, count, flags, addr, addrlen, ec); // Check if operation succeeded. if (bytes >= 0) @@ -913,7 +983,8 @@ bool non_blocking_recvfrom(socket_type s, for (;;) { // Read some data. - int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, ec); + signed_size_type bytes = socket_ops::recvfrom( + s, bufs, count, flags, addr, addrlen, ec); // Retry operation if interrupted by signal. if (ec == boost::asio::error::interrupted) @@ -939,18 +1010,18 @@ bool non_blocking_recvfrom(socket_type s, #endif // defined(BOOST_ASIO_HAS_IOCP) -int recvmsg(socket_type s, buf* bufs, size_t count, +signed_size_type recvmsg(socket_type s, buf* bufs, size_t count, int in_flags, int& out_flags, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) out_flags = 0; return socket_ops::recv(s, bufs, count, in_flags, ec); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); msg.msg_iov = bufs; - msg.msg_iovlen = count; - int result = error_wrapper(::recvmsg(s, &msg, in_flags), ec); + msg.msg_iovlen = static_cast(count); + signed_size_type result = error_wrapper(::recvmsg(s, &msg, in_flags), ec); if (result >= 0) { ec = boost::system::error_code(); @@ -959,7 +1030,7 @@ int recvmsg(socket_type s, buf* bufs, size_t count, else out_flags = 0; return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_recvmsg(socket_type s, state_type state, @@ -976,7 +1047,8 @@ size_t sync_recvmsg(socket_type s, state_type state, for (;;) { // Try to complete the operation without blocking. - int bytes = socket_ops::recvmsg(s, bufs, count, in_flags, out_flags, ec); + signed_size_type bytes = socket_ops::recvmsg( + s, bufs, count, in_flags, out_flags, ec); // Check if operation succeeded. if (bytes >= 0) @@ -1023,7 +1095,8 @@ bool non_blocking_recvmsg(socket_type s, for (;;) { // Read some data. - int bytes = socket_ops::recvmsg(s, bufs, count, in_flags, out_flags, ec); + signed_size_type bytes = socket_ops::recvmsg( + s, bufs, count, in_flags, out_flags, ec); // Retry operation if interrupted by signal. if (ec == boost::asio::error::interrupted) @@ -1049,11 +1122,11 @@ bool non_blocking_recvmsg(socket_type s, #endif // defined(BOOST_ASIO_HAS_IOCP) -int send(socket_type s, const buf* bufs, size_t count, int flags, - boost::system::error_code& ec) +signed_size_type send(socket_type s, const buf* bufs, size_t count, + int flags, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Send the data. DWORD send_buf_count = static_cast(count); DWORD bytes_transferred = 0; @@ -1068,18 +1141,18 @@ int send(socket_type s, const buf* bufs, size_t count, int flags, return socket_error_retval; ec = boost::system::error_code(); return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); msg.msg_iov = const_cast(bufs); - msg.msg_iovlen = count; + msg.msg_iovlen = static_cast(count); #if defined(__linux__) flags |= MSG_NOSIGNAL; #endif // defined(__linux__) - int result = error_wrapper(::sendmsg(s, &msg, flags), ec); + signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec); if (result >= 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_send(socket_type s, state_type state, const buf* bufs, @@ -1102,7 +1175,7 @@ size_t sync_send(socket_type s, state_type state, const buf* bufs, for (;;) { // Try to complete the operation without blocking. - int bytes = socket_ops::send(s, bufs, count, flags, ec); + signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec); // Check if operation succeeded. if (bytes >= 0) @@ -1149,7 +1222,7 @@ bool non_blocking_send(socket_type s, for (;;) { // Write some data. - int bytes = socket_ops::send(s, bufs, count, flags, ec); + signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec); // Retry operation if interrupted by signal. if (ec == boost::asio::error::interrupted) @@ -1175,12 +1248,12 @@ bool non_blocking_send(socket_type s, #endif // defined(BOOST_ASIO_HAS_IOCP) -int sendto(socket_type s, const buf* bufs, size_t count, int flags, - const socket_addr_type* addr, std::size_t addrlen, +signed_size_type sendto(socket_type s, const buf* bufs, size_t count, + int flags, const socket_addr_type* addr, std::size_t addrlen, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Send the data. DWORD send_buf_count = static_cast(count); DWORD bytes_transferred = 0; @@ -1195,20 +1268,20 @@ int sendto(socket_type s, const buf* bufs, size_t count, int flags, return socket_error_retval; ec = boost::system::error_code(); return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = addrlen; + msg.msg_namelen = static_cast(addrlen); msg.msg_iov = const_cast(bufs); - msg.msg_iovlen = count; + msg.msg_iovlen = static_cast(count); #if defined(__linux__) flags |= MSG_NOSIGNAL; #endif // defined(__linux__) - int result = error_wrapper(::sendmsg(s, &msg, flags), ec); + signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec); if (result >= 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_sendto(socket_type s, state_type state, const buf* bufs, @@ -1225,7 +1298,8 @@ size_t sync_sendto(socket_type s, state_type state, const buf* bufs, for (;;) { // Try to complete the operation without blocking. - int bytes = socket_ops::sendto(s, bufs, count, flags, addr, addrlen, ec); + signed_size_type bytes = socket_ops::sendto( + s, bufs, count, flags, addr, addrlen, ec); // Check if operation succeeded. if (bytes >= 0) @@ -1253,7 +1327,8 @@ bool non_blocking_sendto(socket_type s, for (;;) { // Write some data. - int bytes = socket_ops::sendto(s, bufs, count, flags, addr, addrlen, ec); + signed_size_type bytes = socket_ops::sendto( + s, bufs, count, flags, addr, addrlen, ec); // Retry operation if interrupted by signal. if (ec == boost::asio::error::interrupted) @@ -1283,13 +1358,13 @@ socket_type socket(int af, int type, int protocol, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - socket_type s = error_wrapper(::WSASocket(af, type, protocol, 0, 0, +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + socket_type s = error_wrapper(::WSASocketW(af, type, protocol, 0, 0, WSA_FLAG_OVERLAPPED), ec); if (s == invalid_socket) return s; - if (af == AF_INET6) + if (af == BOOST_ASIO_OS_DEF(AF_INET6)) { // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to // false. This will only succeed on Windows Vista and later versions of @@ -1481,7 +1556,7 @@ int getsockopt(socket_type s, state_type state, int level, int optname, } ec = boost::asio::error::fault; return socket_error_retval; -#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) clear_last_error(); int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, s, level, optname, optval, optlen), ec); @@ -1499,7 +1574,7 @@ int getsockopt(socket_type s, state_type state, int level, int optname, if (result == 0) ec = boost::system::error_code(); return result; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) clear_last_error(); int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, s, level, optname, optval, optlen), ec); @@ -1518,7 +1593,7 @@ int getsockopt(socket_type s, state_type state, int level, int optname, if (result == 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } template @@ -1540,7 +1615,7 @@ int getpeername(socket_type s, socket_addr_type* addr, return socket_error_retval; } -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) if (cached) { // Check if socket is still connected. @@ -1561,9 +1636,9 @@ int getpeername(socket_type s, socket_addr_type* addr, ec = boost::system::error_code(); return 0; } -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) (void)cached; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) clear_last_error(); int result = error_wrapper(call_getpeername( @@ -1610,7 +1685,7 @@ int ioctl(socket_type s, state_type& state, int cmd, } clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec); #elif defined(__MACH__) && defined(__APPLE__) \ || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) @@ -1651,7 +1726,7 @@ int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) if (!readfds && !writefds && !exceptfds && timeout) { DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; @@ -1671,7 +1746,7 @@ int select(int nfds, fd_set* readfds, fd_set* writefds, if (timeout && timeout->tv_sec == 0 && timeout->tv_usec > 0 && timeout->tv_usec < 1000) timeout->tv_usec = 1000; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) #if defined(__hpux) && defined(__SELECT) timespec ts; @@ -1696,7 +1771,7 @@ int poll_read(socket_type s, state_type state, boost::system::error_code& ec) return socket_error_retval; } -#if defined(BOOST_WINDOWS) \ +#if defined(BOOST_ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set fds; @@ -1707,8 +1782,8 @@ int poll_read(socket_type s, state_type state, boost::system::error_code& ec) zero_timeout.tv_usec = 0; timeval* timeout = (state & user_set_non_blocking) ? &zero_timeout : 0; clear_last_error(); - int result = error_wrapper(::select(s, &fds, 0, 0, timeout), ec); -#else // defined(BOOST_WINDOWS) + int result = error_wrapper(::select(s + 1, &fds, 0, 0, timeout), ec); +#else // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; @@ -1718,7 +1793,7 @@ int poll_read(socket_type s, state_type state, boost::system::error_code& ec) int timeout = (state & user_set_non_blocking) ? 0 : -1; clear_last_error(); int result = error_wrapper(::poll(&fds, 1, timeout), ec); -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) if (result == 0) @@ -1737,7 +1812,7 @@ int poll_write(socket_type s, state_type state, boost::system::error_code& ec) return socket_error_retval; } -#if defined(BOOST_WINDOWS) \ +#if defined(BOOST_ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set fds; @@ -1748,8 +1823,8 @@ int poll_write(socket_type s, state_type state, boost::system::error_code& ec) zero_timeout.tv_usec = 0; timeval* timeout = (state & user_set_non_blocking) ? &zero_timeout : 0; clear_last_error(); - int result = error_wrapper(::select(s, 0, &fds, 0, timeout), ec); -#else // defined(BOOST_WINDOWS) + int result = error_wrapper(::select(s + 1, 0, &fds, 0, timeout), ec); +#else // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; @@ -1759,7 +1834,7 @@ int poll_write(socket_type s, state_type state, boost::system::error_code& ec) int timeout = (state & user_set_non_blocking) ? 0 : -1; clear_last_error(); int result = error_wrapper(::poll(&fds, 1, timeout), ec); -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) if (result == 0) @@ -1778,7 +1853,7 @@ int poll_connect(socket_type s, boost::system::error_code& ec) return socket_error_retval; } -#if defined(BOOST_WINDOWS) \ +#if defined(BOOST_ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set write_fds; @@ -1788,11 +1863,12 @@ int poll_connect(socket_type s, boost::system::error_code& ec) FD_ZERO(&except_fds); FD_SET(s, &except_fds); clear_last_error(); - int result = error_wrapper(::select(s, 0, &write_fds, &except_fds, 0), ec); + int result = error_wrapper(::select( + s + 1, 0, &write_fds, &except_fds, 0), ec); if (result >= 0) ec = boost::system::error_code(); return result; -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; @@ -1804,19 +1880,56 @@ int poll_connect(socket_type s, boost::system::error_code& ec) if (result >= 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) } +#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) + const char* inet_ntop(int af, const void* src, char* dest, size_t length, unsigned long scope_id, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + using namespace std; // For sprintf. + const unsigned char* bytes = static_cast(src); + if (af == BOOST_ASIO_OS_DEF(AF_INET)) + { + sprintf_s(dest, length, "%u.%u.%u.%u", + bytes[0], bytes[1], bytes[2], bytes[3]); + return dest; + } + else if (af == BOOST_ASIO_OS_DEF(AF_INET6)) + { + size_t n = 0, b = 0, z = 0; + while (n < length && b < 16) + { + if (bytes[b] == 0 && bytes[b + 1] == 0 && z == 0) + { + do b += 2; while (b < 16 && bytes[b] == 0 && bytes[b + 1] == 0); + n += sprintf_s(dest + n, length - n, ":%s", b < 16 ? "" : ":"), ++z; + } + else + { + n += sprintf_s(dest + n, length - n, "%s%x", b ? ":" : "", + (static_cast(bytes[b]) << 8) | bytes[b + 1]); + b += 2; + } + } + if (scope_id) + n += sprintf_s(dest + n, length - n, "%%%lu", scope_id); + return dest; + } + else + { + ec = boost::asio::error::address_family_not_supported; + return 0; + } +#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) using namespace std; // For memcpy. - if (af != AF_INET && af != AF_INET6) + if (af != BOOST_ASIO_OS_DEF(AF_INET) && af != BOOST_ASIO_OS_DEF(AF_INET6)) { ec = boost::asio::error::address_family_not_supported; return 0; @@ -1830,17 +1943,17 @@ const char* inet_ntop(int af, const void* src, char* dest, size_t length, sockaddr_in6_type v6; } address; DWORD address_length; - if (af == AF_INET) + if (af == BOOST_ASIO_OS_DEF(AF_INET)) { address_length = sizeof(sockaddr_in4_type); - address.v4.sin_family = AF_INET; + address.v4.sin_family = BOOST_ASIO_OS_DEF(AF_INET); address.v4.sin_port = 0; memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type)); } else // AF_INET6 { address_length = sizeof(sockaddr_in6_type); - address.v6.sin6_family = AF_INET6; + address.v6.sin6_family = BOOST_ASIO_OS_DEF(AF_INET6); address.v6.sin6_port = 0; address.v6.sin6_flowinfo = 0; address.v6.sin6_scope_id = scope_id; @@ -1848,11 +1961,12 @@ const char* inet_ntop(int af, const void* src, char* dest, size_t length, } DWORD string_length = static_cast(length); -#if defined(BOOST_NO_ANSI_APIS) +#if defined(BOOST_NO_ANSI_APIS) || (defined(_MSC_VER) && (_MSC_VER >= 1800)) LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR)); int result = error_wrapper(::WSAAddressToStringW(&address.base, address_length, 0, string_buffer, &string_length), ec); - ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0); + ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, + dest, static_cast(length), 0, 0); #else int result = error_wrapper(::WSAAddressToStringA( &address.base, address_length, 0, dest, &string_length), ec); @@ -1867,33 +1981,181 @@ const char* inet_ntop(int af, const void* src, char* dest, size_t length, ec = boost::asio::error::invalid_argument; return result == socket_error_retval ? 0 : dest; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - const char* result = error_wrapper(::inet_ntop(af, src, dest, length), ec); +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + const char* result = error_wrapper(::inet_ntop( + af, src, dest, static_cast(length)), ec); if (result == 0 && !ec) ec = boost::asio::error::invalid_argument; - if (result != 0 && af == AF_INET6 && scope_id != 0) + if (result != 0 && af == BOOST_ASIO_OS_DEF(AF_INET6) && scope_id != 0) { using namespace std; // For strcat and sprintf. char if_name[IF_NAMESIZE + 1] = "%"; const in6_addr_type* ipv6_address = static_cast(src); bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe) && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80)); - if (!is_link_local || if_indextoname(scope_id, if_name + 1) == 0) + bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff) + && ((ipv6_address->s6_addr[1] & 0x0f) == 0x02)); + if ((!is_link_local && !is_multicast_link_local) + || if_indextoname(static_cast(scope_id), if_name + 1) == 0) sprintf(if_name + 1, "%lu", scope_id); strcat(dest, if_name); } return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } int inet_pton(int af, const char* src, void* dest, unsigned long* scope_id, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + using namespace std; // For sscanf. + unsigned char* bytes = static_cast(dest); + if (af == BOOST_ASIO_OS_DEF(AF_INET)) + { + unsigned int b0, b1, b2, b3; + if (sscanf_s(src, "%u.%u.%u.%u", &b0, &b1, &b2, &b3) != 4) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + if (b0 > 255 || b1 > 255 || b2 > 255 || b3 > 255) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + bytes[0] = static_cast(b0); + bytes[1] = static_cast(b1); + bytes[2] = static_cast(b2); + bytes[3] = static_cast(b3); + ec = boost::system::error_code(); + return 1; + } + else if (af == BOOST_ASIO_OS_DEF(AF_INET6)) + { + unsigned char* bytes = static_cast(dest); + std::memset(bytes, 0, 16); + unsigned char back_bytes[16] = { 0 }; + int num_front_bytes = 0, num_back_bytes = 0; + const char* p = src; + + enum { fword, fcolon, bword, scope, done } state = fword; + unsigned long current_word = 0; + while (state != done) + { + if (current_word > 0xFFFF) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + + switch (state) + { + case fword: + if (*p >= '0' && *p <= '9') + current_word = current_word * 16 + *p++ - '0'; + else if (*p >= 'a' && *p <= 'f') + current_word = current_word * 16 + *p++ - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') + current_word = current_word * 16 + *p++ - 'A' + 10; + else + { + if (num_front_bytes == 16) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + + bytes[num_front_bytes++] = (current_word >> 8) & 0xFF; + bytes[num_front_bytes++] = current_word & 0xFF; + current_word = 0; + + if (*p == ':') + state = fcolon, ++p; + else if (*p == '%') + state = scope, ++p; + else if (*p == 0) + state = done; + else + { + ec = boost::asio::error::invalid_argument; + return -1; + } + } + break; + + case fcolon: + if (*p == ':') + state = bword, ++p; + else + state = fword; + break; + + case bword: + if (*p >= '0' && *p <= '9') + current_word = current_word * 16 + *p++ - '0'; + else if (*p >= 'a' && *p <= 'f') + current_word = current_word * 16 + *p++ - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') + current_word = current_word * 16 + *p++ - 'A' + 10; + else + { + if (num_front_bytes + num_back_bytes == 16) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + + back_bytes[num_back_bytes++] = (current_word >> 8) & 0xFF; + back_bytes[num_back_bytes++] = current_word & 0xFF; + current_word = 0; + + if (*p == ':') + state = bword, ++p; + else if (*p == '%') + state = scope, ++p; + else if (*p == 0) + state = done; + else + { + ec = boost::asio::error::invalid_argument; + return -1; + } + } + break; + + case scope: + if (*p >= '0' && *p <= '9') + current_word = current_word * 10 + *p++ - '0'; + else if (*p == 0) + *scope_id = current_word, state = done; + else + { + ec = boost::asio::error::invalid_argument; + return -1; + } + break; + + default: + break; + } + } + + for (int i = 0; i < num_back_bytes; ++i) + bytes[16 - num_back_bytes + i] = back_bytes[i]; + + ec = boost::system::error_code(); + return 1; + } + else + { + ec = boost::asio::error::address_family_not_supported; + return -1; + } +#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) using namespace std; // For memcpy and strcmp. - if (af != AF_INET && af != AF_INET6) + if (af != BOOST_ASIO_OS_DEF(AF_INET) && af != BOOST_ASIO_OS_DEF(AF_INET6)) { ec = boost::asio::error::address_family_not_supported; return -1; @@ -1907,8 +2169,8 @@ int inet_pton(int af, const char* src, void* dest, sockaddr_in6_type v6; } address; int address_length = sizeof(sockaddr_storage_type); -#if defined(BOOST_NO_ANSI_APIS) - int num_wide_chars = strlen(src) + 1; +#if defined(BOOST_NO_ANSI_APIS) || (defined(_MSC_VER) && (_MSC_VER >= 1800)) + int num_wide_chars = static_cast(strlen(src)) + 1; LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR)); ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars); int result = error_wrapper(::WSAStringToAddressW( @@ -1918,7 +2180,7 @@ int inet_pton(int af, const char* src, void* dest, const_cast(src), af, 0, &address.base, &address_length), ec); #endif - if (af == AF_INET) + if (af == BOOST_ASIO_OS_DEF(AF_INET)) { if (result != socket_error_retval) { @@ -1950,11 +2212,11 @@ int inet_pton(int af, const char* src, void* dest, ec = boost::system::error_code(); return result == socket_error_retval ? -1 : 1; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::inet_pton(af, src, dest), ec); if (result <= 0 && !ec) ec = boost::asio::error::invalid_argument; - if (result > 0 && af == AF_INET6 && scope_id) + if (result > 0 && af == BOOST_ASIO_OS_DEF(AF_INET6) && scope_id) { using namespace std; // For strchr and atoi. *scope_id = 0; @@ -1963,29 +2225,63 @@ int inet_pton(int af, const char* src, void* dest, in6_addr_type* ipv6_address = static_cast(dest); bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe) && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80)); - if (is_link_local) + bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff) + && ((ipv6_address->s6_addr[1] & 0x0f) == 0x02)); + if (is_link_local || is_multicast_link_local) *scope_id = if_nametoindex(if_name + 1); if (*scope_id == 0) *scope_id = atoi(if_name + 1); } } return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } int gethostname(char* name, int namelen, boost::system::error_code& ec) { clear_last_error(); +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + try + { + using namespace Windows::Foundation::Collections; + using namespace Windows::Networking; + using namespace Windows::Networking::Connectivity; + IVectorView^ hostnames = NetworkInformation::GetHostNames(); + for (unsigned i = 0; i < hostnames->Size; ++i) + { + HostName^ hostname = hostnames->GetAt(i); + if (hostname->Type == HostNameType::DomainName) + { + std::wstring_convert> converter; + std::string raw_name = converter.to_bytes(hostname->RawName->Data()); + if (namelen > 0 && raw_name.size() < static_cast(namelen)) + { + strcpy_s(name, namelen, raw_name.c_str()); + return 0; + } + } + } + return -1; + } + catch (Platform::Exception^ e) + { + ec = boost::system::error_code(e->HResult, + boost::system::system_category()); + return -1; + } +#else // defined(BOOST_ASIO_WINDOWS_RUNTIME) int result = error_wrapper(::gethostname(name, namelen), ec); -#if defined(BOOST_WINDOWS) +# if defined(BOOST_ASIO_WINDOWS) if (result == 0) ec = boost::system::error_code(); -#endif +# endif // defined(BOOST_ASIO_WINDOWS) return result; +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) } -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \ - || defined(__MACH__) && defined(__APPLE__) +#if !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#if !defined(BOOST_ASIO_HAS_GETADDRINFO) // The following functions are only needed for emulation of getaddrinfo and // getnameinfo. @@ -2005,7 +2301,7 @@ inline boost::system::error_code translate_netdb_error(int error) case NO_DATA: return boost::asio::error::no_data; default: - BOOST_ASSERT(false); + BOOST_ASIO_ASSERT(false); return boost::asio::error::invalid_argument; } } @@ -2014,7 +2310,7 @@ inline hostent* gethostbyaddr(const char* addr, int length, int af, hostent* result, char* buffer, int buflength, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) (void)(buffer); (void)(buflength); hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec); @@ -2057,11 +2353,11 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result, char* buffer, int buflength, int ai_flags, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) (void)(buffer); (void)(buflength); (void)(ai_flags); - if (af != AF_INET) + if (af != BOOST_ASIO_OS_DEF(AF_INET)) { ec = boost::asio::error::address_family_not_supported; return 0; @@ -2074,7 +2370,7 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result, return result; #elif defined(__sun) || defined(__QNX__) (void)(ai_flags); - if (af != AF_INET) + if (af != BOOST_ASIO_OS_DEF(AF_INET)) { ec = boost::asio::error::address_family_not_supported; return 0; @@ -2099,7 +2395,7 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result, return retval; #else (void)(ai_flags); - if (af != AF_INET) + if (af != BOOST_ASIO_OS_DEF(AF_INET)) { ec = boost::asio::error::address_family_not_supported; return 0; @@ -2144,22 +2440,22 @@ inline int gai_nsearch(const char* host, // No host and AI_PASSIVE implies wildcard bind. switch (hints->ai_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): search[search_count].host = "0.0.0.0"; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): search[search_count].host = "0::0"; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; break; - case AF_UNSPEC: + case BOOST_ASIO_OS_DEF(AF_UNSPEC): search[search_count].host = "0::0"; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; search[search_count].host = "0.0.0.0"; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; default: @@ -2171,22 +2467,22 @@ inline int gai_nsearch(const char* host, // No host and not AI_PASSIVE means connect to local host. switch (hints->ai_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): search[search_count].host = "localhost"; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): search[search_count].host = "localhost"; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; break; - case AF_UNSPEC: + case BOOST_ASIO_OS_DEF(AF_UNSPEC): search[search_count].host = "localhost"; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; search[search_count].host = "localhost"; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; default: @@ -2199,22 +2495,22 @@ inline int gai_nsearch(const char* host, // Host is specified. switch (hints->ai_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): search[search_count].host = host; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): search[search_count].host = host; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; break; - case AF_UNSPEC: + case BOOST_ASIO_OS_DEF(AF_UNSPEC): search[search_count].host = host; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; search[search_count].host = host; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; default: @@ -2242,12 +2538,12 @@ inline void gai_free(void* p) inline void gai_strcpy(char* target, const char* source, std::size_t max_size) { using namespace std; -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) +#if defined(BOOST_ASIO_HAS_SECURE_RTL) strcpy_s(target, max_size, source); -#else +#else // defined(BOOST_ASIO_HAS_SECURE_RTL) *target = 0; strncat(target, source, max_size); -#endif +#endif // defined(BOOST_ASIO_HAS_SECURE_RTL) } enum { gai_clone_flag = 1 << 30 }; @@ -2274,23 +2570,23 @@ inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints, switch (ai->ai_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): { sockaddr_in4_type* sinptr = gai_alloc(); if (sinptr == 0) return EAI_MEMORY; - sinptr->sin_family = AF_INET; + sinptr->sin_family = BOOST_ASIO_OS_DEF(AF_INET); memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type)); ai->ai_addr = reinterpret_cast(sinptr); ai->ai_addrlen = sizeof(sockaddr_in4_type); break; } - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): { sockaddr_in6_type* sin6ptr = gai_alloc(); if (sin6ptr == 0) return EAI_MEMORY; - sin6ptr->sin6_family = AF_INET6; + sin6ptr->sin6_family = BOOST_ASIO_OS_DEF(AF_INET6); memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type)); ai->ai_addr = reinterpret_cast(sin6ptr); ai->ai_addrlen = sizeof(sockaddr_in6_type); @@ -2352,7 +2648,7 @@ inline int gai_port(addrinfo_type* aihead, int port, int socktype) switch (ai->ai_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): { sockaddr_in4_type* sinptr = reinterpret_cast(ai->ai_addr); @@ -2360,7 +2656,7 @@ inline int gai_port(addrinfo_type* aihead, int port, int socktype) ++num_found; break; } - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): { sockaddr_in6_type* sin6ptr = reinterpret_cast(ai->ai_addr); @@ -2469,10 +2765,10 @@ inline int gai_echeck(const char* host, const char* service, // Check combination of family and socket type. switch (family) { - case AF_UNSPEC: + case BOOST_ASIO_OS_DEF(AF_UNSPEC): break; - case AF_INET: - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET): + case BOOST_ASIO_OS_DEF(AF_INET6): if (service != 0 && service[0] != '\0') if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM) return EAI_SOCKTYPE; @@ -2507,18 +2803,18 @@ inline int getaddrinfo_emulation(const char* host, const char* service, // Supply default hints if not specified by caller. addrinfo_type hints = addrinfo_type(); - hints.ai_family = AF_UNSPEC; + hints.ai_family = BOOST_ASIO_OS_DEF(AF_UNSPEC); if (hintsp) hints = *hintsp; // If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED // and AI_ALL flags. #if defined(AI_V4MAPPED) - if (hints.ai_family != AF_INET6) + if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6)) hints.ai_flags &= ~AI_V4MAPPED; #endif #if defined(AI_ALL) - if (hints.ai_family != AF_INET6) + if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6)) hints.ai_flags &= ~AI_ALL; #endif @@ -2538,17 +2834,19 @@ inline int getaddrinfo_emulation(const char* host, const char* service, // Check for IPv4 dotted decimal string. in4_addr_type inaddr; boost::system::error_code ec; - if (socket_ops::inet_pton(AF_INET, sptr->host, &inaddr, 0, ec) == 1) + if (socket_ops::inet_pton(BOOST_ASIO_OS_DEF(AF_INET), + sptr->host, &inaddr, 0, ec) == 1) { - if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET) + if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC) + && hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET)) { freeaddrinfo_emulation(aihead); gai_free(canon); return EAI_FAMILY; } - if (sptr->family == AF_INET) + if (sptr->family == BOOST_ASIO_OS_DEF(AF_INET)) { - rc = gai_aistruct(&ainext, &hints, &inaddr, AF_INET); + rc = gai_aistruct(&ainext, &hints, &inaddr, BOOST_ASIO_OS_DEF(AF_INET)); if (rc != 0) { freeaddrinfo_emulation(aihead); @@ -2561,17 +2859,20 @@ inline int getaddrinfo_emulation(const char* host, const char* service, // Check for IPv6 hex string. in6_addr_type in6addr; - if (socket_ops::inet_pton(AF_INET6, sptr->host, &in6addr, 0, ec) == 1) + if (socket_ops::inet_pton(BOOST_ASIO_OS_DEF(AF_INET6), + sptr->host, &in6addr, 0, ec) == 1) { - if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET6) + if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC) + && hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6)) { freeaddrinfo_emulation(aihead); gai_free(canon); return EAI_FAMILY; } - if (sptr->family == AF_INET6) + if (sptr->family == BOOST_ASIO_OS_DEF(AF_INET6)) { - rc = gai_aistruct(&ainext, &hints, &in6addr, AF_INET6); + rc = gai_aistruct(&ainext, &hints, &in6addr, + BOOST_ASIO_OS_DEF(AF_INET6)); if (rc != 0) { freeaddrinfo_emulation(aihead); @@ -2608,7 +2909,8 @@ inline int getaddrinfo_emulation(const char* host, const char* service, } // Check for address family mismatch if one was specified. - if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype) + if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC) + && hints.ai_family != hptr->h_addrtype) { freeaddrinfo_emulation(aihead); gai_free(canon); @@ -2704,7 +3006,7 @@ inline boost::system::error_code getnameinfo_emulation( unsigned short port; switch (sa->sa_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): if (salen != sizeof(sockaddr_in4_type)) { return ec = boost::asio::error::invalid_argument; @@ -2714,7 +3016,7 @@ inline boost::system::error_code getnameinfo_emulation( addr_len = sizeof(in4_addr_type); port = reinterpret_cast(sa)->sin_port; break; - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): if (salen != sizeof(sockaddr_in6_type)) { return ec = boost::asio::error::invalid_argument; @@ -2781,20 +3083,18 @@ inline boost::system::error_code getnameinfo_emulation( { return ec = boost::asio::error::no_buffer_space; } -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) +#if defined(BOOST_ASIO_HAS_SECURE_RTL) sprintf_s(serv, servlen, "%u", ntohs(port)); -#else +#else // defined(BOOST_ASIO_HAS_SECURE_RTL) sprintf(serv, "%u", ntohs(port)); -#endif +#endif // defined(BOOST_ASIO_HAS_SECURE_RTL) } else { -#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) \ - && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_PTHREADS) static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ::pthread_mutex_lock(&mutex); -#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) - // && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_PTHREADS) servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0); if (sptr && sptr->s_name && sptr->s_name[0] != '\0') { @@ -2806,17 +3106,15 @@ inline boost::system::error_code getnameinfo_emulation( { return ec = boost::asio::error::no_buffer_space; } -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) +#if defined(BOOST_ASIO_HAS_SECURE_RTL) sprintf_s(serv, servlen, "%u", ntohs(port)); -#else +#else // defined(BOOST_ASIO_HAS_SECURE_RTL) sprintf(serv, "%u", ntohs(port)); -#endif +#endif // defined(BOOST_ASIO_HAS_SECURE_RTL) } -#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) \ - && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_PTHREADS) ::pthread_mutex_unlock(&mutex); -#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) - // && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_PTHREADS) } } @@ -2824,8 +3122,7 @@ inline boost::system::error_code getnameinfo_emulation( return ec; } -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - // || defined(__MACH__) && defined(__APPLE__) +#endif // !defined(BOOST_ASIO_HAS_GETADDRINFO) inline boost::system::error_code translate_addrinfo_error(int error) { @@ -2856,7 +3153,7 @@ inline boost::system::error_code translate_addrinfo_error(int error) case EAI_SOCKTYPE: return boost::asio::error::socket_type_not_supported; default: // Possibly the non-portable EAI_SYSTEM. -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) return boost::system::error_code( WSAGetLastError(), boost::asio::error::get_system_category()); #else @@ -2873,8 +3170,8 @@ boost::system::error_code getaddrinfo(const char* host, host = (host && *host) ? host : 0; service = (service && *service) ? service : 0; clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_HAS_GETADDRINFO) // Building for Windows XP, Windows Server 2003, or later. int error = ::getaddrinfo(host, service, &hints, result); return ec = translate_addrinfo_error(error); @@ -2893,7 +3190,7 @@ boost::system::error_code getaddrinfo(const char* host, int error = getaddrinfo_emulation(host, service, &hints, result); return ec = translate_addrinfo_error(error); # endif -#elif defined(__MACH__) && defined(__APPLE__) +#elif !defined(BOOST_ASIO_HAS_GETADDRINFO) int error = getaddrinfo_emulation(host, service, &hints, result); return ec = translate_addrinfo_error(error); #else @@ -2916,8 +3213,8 @@ boost::system::error_code background_getaddrinfo( void freeaddrinfo(addrinfo_type* ai) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_HAS_GETADDRINFO) // Building for Windows XP, Windows Server 2003, or later. ::freeaddrinfo(ai); # else @@ -2933,7 +3230,7 @@ void freeaddrinfo(addrinfo_type* ai) } freeaddrinfo_emulation(ai); # endif -#elif defined(__MACH__) && defined(__APPLE__) +#elif !defined(BOOST_ASIO_HAS_GETADDRINFO) freeaddrinfo_emulation(ai); #else ::freeaddrinfo(ai); @@ -2944,8 +3241,8 @@ boost::system::error_code getnameinfo(const socket_addr_type* addr, std::size_t addrlen, char* host, std::size_t hostlen, char* serv, std::size_t servlen, int flags, boost::system::error_code& ec) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_HAS_GETADDRINFO) // Building for Windows XP, Windows Server 2003, or later. clear_last_error(); int error = ::getnameinfo(addr, static_cast(addrlen), @@ -2971,7 +3268,7 @@ boost::system::error_code getnameinfo(const socket_addr_type* addr, return getnameinfo_emulation(addr, addrlen, host, hostlen, serv, servlen, flags, ec); # endif -#elif defined(__MACH__) && defined(__APPLE__) +#elif !defined(BOOST_ASIO_HAS_GETADDRINFO) using namespace std; // For memcpy. sockaddr_storage_type tmp_addr; memcpy(&tmp_addr, addr, addrlen); @@ -3033,24 +3330,60 @@ boost::system::error_code background_getnameinfo( return ec; } +#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) + u_long_type network_to_host_long(u_long_type value) { +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + unsigned char* value_p = reinterpret_cast(&value); + u_long_type result = (static_cast(value_p[0]) << 24) + | (static_cast(value_p[1]) << 16) + | (static_cast(value_p[2]) << 8) + | static_cast(value_p[3]); + return result; +#else // defined(BOOST_ASIO_WINDOWS_RUNTIME) return ntohl(value); +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) } u_long_type host_to_network_long(u_long_type value) { +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + u_long_type result; + unsigned char* result_p = reinterpret_cast(&result); + result_p[0] = static_cast((value >> 24) & 0xFF); + result_p[1] = static_cast((value >> 16) & 0xFF); + result_p[2] = static_cast((value >> 8) & 0xFF); + result_p[3] = static_cast(value & 0xFF); + return result; +#else // defined(BOOST_ASIO_WINDOWS_RUNTIME) return htonl(value); +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) } u_short_type network_to_host_short(u_short_type value) { +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + unsigned char* value_p = reinterpret_cast(&value); + u_short_type result = (static_cast(value_p[0]) << 8) + | static_cast(value_p[1]); + return result; +#else // defined(BOOST_ASIO_WINDOWS_RUNTIME) return ntohs(value); +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) } u_short_type host_to_network_short(u_short_type value) { +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + u_short_type result; + unsigned char* result_p = reinterpret_cast(&result); + result_p[0] = static_cast((value >> 8) & 0xFF); + result_p[1] = static_cast(value & 0xFF); + return result; +#else // defined(BOOST_ASIO_WINDOWS_RUNTIME) return htons(value); +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) } } // namespace socket_ops -- cgit v1.2.3