POSIX allows successful system calls to modify errno, so always clear the error_code if the result indicates success.
diff --git a/asio/include/asio/detail/descriptor_ops.hpp b/asio/include/asio/detail/descriptor_ops.hpp index e886b27..c038386 100644 --- a/asio/include/asio/detail/descriptor_ops.hpp +++ b/asio/include/asio/detail/descriptor_ops.hpp
@@ -49,13 +49,19 @@ inline int open(const char* path, int flags, asio::error_code& ec) { clear_error(ec); - return error_wrapper(::open(path, flags), ec); + int result = error_wrapper(::open(path, flags), ec); + if (result >= 0) + clear_error(ec); + return result; } inline int close(int d, asio::error_code& ec) { clear_error(ec); - return error_wrapper(::close(d), ec); + int result = error_wrapper(::close(d), ec); + if (result == 0) + clear_error(ec); + return result; } inline void init_buf_iov_base(void*& base, void* addr) @@ -87,33 +93,48 @@ asio::error_code& ec) { clear_error(ec); - return error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec); + int result = error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec); + if (result >= 0) + clear_error(ec); + return result; } inline int gather_write(int d, const buf* bufs, size_t count, asio::error_code& ec) { clear_error(ec); - return error_wrapper(::writev(d, bufs, static_cast<int>(count)), ec); + int result = error_wrapper(::writev(d, bufs, static_cast<int>(count)), ec); + if (result >= 0) + clear_error(ec); + return result; } inline int ioctl(int d, long cmd, ioctl_arg_type* arg, asio::error_code& ec) { clear_error(ec); - return error_wrapper(::ioctl(d, cmd, arg), ec); + int result = error_wrapper(::ioctl(d, cmd, arg), ec); + if (result >= 0) + clear_error(ec); + return result; } inline int fcntl(int d, long cmd, asio::error_code& ec) { clear_error(ec); - return error_wrapper(::fcntl(d, cmd), ec); + int result = error_wrapper(::fcntl(d, cmd), ec); + if (result != -1) + clear_error(ec); + return result; } inline int fcntl(int d, long cmd, long arg, asio::error_code& ec) { clear_error(ec); - return error_wrapper(::fcntl(d, cmd, arg), ec); + int result = error_wrapper(::fcntl(d, cmd, arg), ec); + if (result != -1) + clear_error(ec); + return result; } inline int poll_read(int d, asio::error_code& ec) @@ -124,7 +145,10 @@ fds.events = POLLIN; fds.revents = 0; clear_error(ec); - return error_wrapper(::poll(&fds, 1, -1), ec); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + clear_error(ec); + return result; } inline int poll_write(int d, asio::error_code& ec) @@ -135,7 +159,10 @@ fds.events = POLLOUT; fds.revents = 0; clear_error(ec); - return error_wrapper(::poll(&fds, 1, -1), ec); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + clear_error(ec); + return result; } } // namespace descriptor_ops
diff --git a/asio/include/asio/detail/socket_ops.hpp b/asio/include/asio/detail/socket_ops.hpp index 1f00b4c..b08cce9 100644 --- a/asio/include/asio/detail/socket_ops.hpp +++ b/asio/include/asio/detail/socket_ops.hpp
@@ -102,10 +102,7 @@ } #endif -#if defined(BOOST_WINDOWS) clear_error(ec); -#endif - return new_s; } @@ -122,10 +119,8 @@ clear_error(ec); int result = error_wrapper(call_bind( &msghdr::msg_namelen, s, addr, addrlen), ec); -#if defined(BOOST_WINDOWS) if (result == 0) clear_error(ec); -#endif return result; } @@ -134,22 +129,20 @@ clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::closesocket(s), ec); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::close(s), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) if (result == 0) clear_error(ec); return result; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - return error_wrapper(::close(s), ec); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } inline int shutdown(socket_type s, int what, asio::error_code& ec) { clear_error(ec); int result = error_wrapper(::shutdown(s, what), ec); -#if defined(BOOST_WINDOWS) if (result == 0) clear_error(ec); -#endif return result; } @@ -166,10 +159,8 @@ clear_error(ec); int result = error_wrapper(call_connect( &msghdr::msg_namelen, s, addr, addrlen), ec); -#if defined(BOOST_WINDOWS) if (result == 0) clear_error(ec); -#endif return result; } @@ -185,7 +176,10 @@ return -1; #else clear_error(ec); - return error_wrapper(::socketpair(af, type, protocol, sv), ec); + int result = error_wrapper(::socketpair(af, type, protocol, sv), ec); + if (result == 0) + clear_error(ec); + return result; #endif } @@ -193,10 +187,8 @@ { clear_error(ec); int result = error_wrapper(::listen(s, backlog), ec); -#if defined(BOOST_WINDOWS) if (result == 0) clear_error(ec); -#endif return result; } @@ -280,7 +272,10 @@ msghdr msg = msghdr(); msg.msg_iov = bufs; msg.msg_iovlen = count; - return error_wrapper(::recvmsg(s, &msg, flags), ec); + int result = error_wrapper(::recvmsg(s, &msg, flags), ec); + if (result >= 0) + clear_error(ec); + return result; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } @@ -310,6 +305,8 @@ msg.msg_iovlen = count; int result = error_wrapper(::recvmsg(s, &msg, flags), ec); *addrlen = msg.msg_namelen; + if (result >= 0) + clear_error(ec); return result; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } @@ -336,7 +333,10 @@ #if defined(__linux__) flags |= MSG_NOSIGNAL; #endif // defined(__linux__) - return error_wrapper(::sendmsg(s, &msg, flags), ec); + int result = error_wrapper(::sendmsg(s, &msg, flags), ec); + if (result >= 0) + clear_error(ec); + return result; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } @@ -365,7 +365,10 @@ #if defined(__linux__) flags |= MSG_NOSIGNAL; #endif // defined(__linux__) - return error_wrapper(::sendmsg(s, &msg, flags), ec); + int result = error_wrapper(::sendmsg(s, &msg, flags), ec); + if (result >= 0) + clear_error(ec); + return result; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } @@ -408,7 +411,10 @@ return s; #else - return error_wrapper(::socket(af, type, protocol), ec); + int s = error_wrapper(::socket(af, type, protocol), ec); + if (s >= 0) + clear_error(ec); + return s; #endif } @@ -451,10 +457,8 @@ clear_error(ec); int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen, s, level, optname, optval, optlen), ec); -# if defined(BOOST_WINDOWS) if (result == 0) clear_error(ec); -# endif return result; #endif // defined(__BORLANDC__) } @@ -543,6 +547,8 @@ *static_cast<int*>(optval) /= 2; } #endif // defined(__linux__) + if (result == 0) + clear_error(ec); return result; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } @@ -563,10 +569,8 @@ clear_error(ec); int result = error_wrapper(call_getpeername( &msghdr::msg_namelen, s, addr, addrlen), ec); -#if defined(BOOST_WINDOWS) if (result == 0) clear_error(ec); -#endif return result; } @@ -586,10 +590,8 @@ clear_error(ec); int result = error_wrapper(call_getsockname( &msghdr::msg_namelen, s, addr, addrlen), ec); -#if defined(BOOST_WINDOWS) if (result == 0) clear_error(ec); -#endif return result; } @@ -599,12 +601,12 @@ clear_error(ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec); - if (result == 0) +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::ioctl(s, cmd, arg), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (result >= 0) clear_error(ec); return result; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - return error_wrapper(::ioctl(s, cmd, arg), ec); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } inline int select(int nfds, fd_set* readfds, fd_set* writefds, @@ -642,10 +644,8 @@ #else int result = error_wrapper(::select(nfds, readfds, writefds, exceptfds, timeout), ec); -# if defined(BOOST_WINDOWS) if (result >= 0) clear_error(ec); -# endif return result; #endif } @@ -667,7 +667,10 @@ fds.events = POLLIN; fds.revents = 0; clear_error(ec); - return error_wrapper(::poll(&fds, 1, -1), ec); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + clear_error(ec); + return result; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } @@ -688,7 +691,10 @@ fds.events = POLLOUT; fds.revents = 0; clear_error(ec); - return error_wrapper(::poll(&fds, 1, -1), ec); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + clear_error(ec); + return result; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) } @@ -712,7 +718,10 @@ fds.events = POLLOUT; fds.revents = 0; clear_error(ec); - return error_wrapper(::poll(&fds, 1, -1), ec); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + clear_error(ec); + return result; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) }