From e665b0aab220943787f42aa12690ff8f5e46f135 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 1 Aug 2012 09:00:53 +0000 Subject: * fhandler.h (fhandler_socket::recv_internal): Add bool parameter. Add regparm attribute. * fhandler_socket.cc (fhandler_socket::read): Call recv_internal with second parameter set to false. (fhandler_socket::readv): Ditto. (fhandler_socket::recvfrom): Ditto. (fhandler_socket::recv_internal): Convert use_recvmsg from local variable to parameter. Use as request for using WSARecvMsg. Only fail if WSARecvMsg can't be loaded and wsamsg->Control.len > 0, otherwise use WSARecv{From}. Restrict dwFlags to MSG_PEEK when using WSARecvMsg. (fhandler_socket::recvmsg): Prefer using WSARecvMsg. Change priority of tests for not using WSARecvMsg. Call recv_internal with second parameter set accordingly. --- winsup/cygwin/fhandler_socket.cc | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'winsup/cygwin/fhandler_socket.cc') diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 054eafea1..a11c7efbe 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -1330,7 +1330,7 @@ fhandler_socket::read (void *in_ptr, size_t& len) { WSABUF wsabuf = { len, (char *) in_ptr }; WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0, NULL }, 0 }; - len = recv_internal (&wsamsg); + len = recv_internal (&wsamsg, false); } int @@ -1346,7 +1346,7 @@ fhandler_socket::readv (const struct iovec *const iov, const int iovcnt, wsaptr->buf = (char *) iovptr->iov_base; } WSAMSG wsamsg = { NULL, 0, wsabuf, iovcnt, { 0, NULL}, 0 }; - return recv_internal (&wsamsg); + return recv_internal (&wsamsg, false); } extern "C" { @@ -1375,28 +1375,32 @@ get_ext_funcptr (SOCKET sock, void *funcptr) } inline ssize_t -fhandler_socket::recv_internal (LPWSAMSG wsamsg) +fhandler_socket::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg) { ssize_t res = 0; DWORD ret = 0, wret; int evt_mask = FD_READ | ((wsamsg->dwFlags & MSG_OOB) ? FD_OOB : 0); LPWSABUF &wsabuf = wsamsg->lpBuffers; ULONG &wsacnt = wsamsg->dwBufferCount; - bool use_recvmsg = false; static NO_COPY LPFN_WSARECVMSG WSARecvMsg; DWORD wait_flags = wsamsg->dwFlags; bool waitall = !!(wait_flags & MSG_WAITALL); wsamsg->dwFlags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE); - if (wsamsg->Control.len > 0) + if (use_recvmsg) { if (!WSARecvMsg && get_ext_funcptr (get_socket (), &WSARecvMsg) == SOCKET_ERROR) { - set_winsock_errno (); - return SOCKET_ERROR; + if (wsamsg->Control.len > 0) + { + set_winsock_errno (); + return SOCKET_ERROR; + } + use_recvmsg = false; } - use_recvmsg = true; + else /* Only MSG_PEEK is supported by WSARecvMsg. */ + wsamsg->dwFlags &= MSG_PEEK; } if (waitall) { @@ -1503,7 +1507,7 @@ fhandler_socket::recvfrom (void *ptr, size_t len, int flags, &wsabuf, 1, { 0, NULL}, flags }; - ssize_t ret = recv_internal (&wsamsg); + ssize_t ret = recv_internal (&wsamsg, false); if (fromlen) *fromlen = wsamsg.namelen; return ret; @@ -1518,12 +1522,12 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags) /* Disappointing but true: Even if WSARecvMsg is supported, it's only supported for datagram and raw sockets. */ - if (!wincap.has_recvmsg () || get_socket_type () == SOCK_STREAM - || get_addr_family () == AF_LOCAL) + bool use_recvmsg = true; + if (get_socket_type () == SOCK_STREAM || get_addr_family () == AF_LOCAL + || !wincap.has_recvmsg ()) { + use_recvmsg = false; msg->msg_controllen = 0; - if (!CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR) - msg->msg_flags = 0; } WSABUF wsabuf[msg->msg_iovlen]; @@ -1538,7 +1542,7 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags) wsabuf, msg->msg_iovlen, { msg->msg_controllen, (char *) msg->msg_control }, flags }; - ssize_t ret = recv_internal (&wsamsg); + ssize_t ret = recv_internal (&wsamsg, use_recvmsg); if (ret >= 0) { msg->msg_namelen = wsamsg.namelen; -- cgit v1.2.3