Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-03-07 17:47:48 +0300
committerCorinna Vinschen <corinna@vinschen.de>2008-03-07 17:47:48 +0300
commit360b05b451fbbc2a2768fa84d86a78ec9002979a (patch)
tree7cb47e1905967070daa56d6e562360e4447461c1 /winsup/cygwin/fhandler_socket.cc
parent752b16ce359bb46948b8aa2bc88f7c32bf2cc95b (diff)
* fhandler_socket.cc (fhandler_socket::sendto): Never send more than
64K. Add comment to explain why. (fhandler_socket::sendmsg): Ditto.
Diffstat (limited to 'winsup/cygwin/fhandler_socket.cc')
-rw-r--r--winsup/cygwin/fhandler_socket.cc23
1 files changed, 17 insertions, 6 deletions
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 07d042df8..33f8ddf7e 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -1393,7 +1393,13 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags,
if (to && !get_inet_addr (to, tolen, &sst, &tolen))
return SOCKET_ERROR;
- WSABUF wsabuf = { len, (char *) ptr };
+ /* Never write more than 64K at once to workaround a problem with
+ Winsock, which creates a temporary buffer with the total incoming
+ buffer size and copies the whole content over, regardless of
+ the size of the internal send buffer. A buffer full condition
+ is only recognized in subsequent calls and, if len is big enough,
+ the call even might fail with an out-of-memory condition. */
+ WSABUF wsabuf = { len > 65536 ? 65536 : len, (char *) ptr };
return send_internal (&wsabuf, 1, flags,
(to ? (const struct sockaddr *) &sst : NULL), tolen);
}
@@ -1411,12 +1417,17 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags)
}
WSABUF wsabuf[msg->msg_iovlen];
- WSABUF *wsaptr = wsabuf + msg->msg_iovlen;
- const struct iovec *iovptr = msg->msg_iov + msg->msg_iovlen;
- while (--wsaptr >= wsabuf)
+ WSABUF *wsaptr = wsabuf;
+ const struct iovec *iovptr = msg->msg_iov;
+ size_t total = 0;
+ for (int i = 0; i < msg->msg_iovlen && total < 65536; ++i)
{
- wsaptr->len = (--iovptr)->iov_len;
- wsaptr->buf = (char *) iovptr->iov_base;
+ if (total + iovptr->iov_len > 65536) /* See above. */
+ wsaptr->len = 65536 - total;
+ else
+ wsaptr->len = iovptr->iov_len;
+ total += wsaptr->len;
+ (wsaptr++)->buf = (char *) (iovptr++)->iov_base;
}
return send_internal (wsabuf, msg->msg_iovlen, flags,