summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler_socket.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2012-08-01 09:00:53 +0000
committerCorinna Vinschen <corinna@vinschen.de>2012-08-01 09:00:53 +0000
commite665b0aab220943787f42aa12690ff8f5e46f135 (patch)
tree2322fde4f99bbccdf2fe89b75805be4a1c4389e9 /winsup/cygwin/fhandler_socket.cc
parent01d9574ddd98856285c85b6f71a0066685fe4790 (diff)
downloadcygnal-e665b0aab220943787f42aa12690ff8f5e46f135.tar.gz
cygnal-e665b0aab220943787f42aa12690ff8f5e46f135.tar.bz2
cygnal-e665b0aab220943787f42aa12690ff8f5e46f135.zip
* 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.
Diffstat (limited to 'winsup/cygwin/fhandler_socket.cc')
-rw-r--r--winsup/cygwin/fhandler_socket.cc32
1 files changed, 18 insertions, 14 deletions
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;