summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2007-11-28 15:54:17 +0000
committerCorinna Vinschen <corinna@vinschen.de>2007-11-28 15:54:17 +0000
commit023a2fa789b7700ed32f8d78655c03b4b273d42b (patch)
treef36b6def4a4268ebaa763e617002748e0fa3d393
parent02cb1fd853c30addf67b6d39f8cf506737ed96ab (diff)
downloadcygnal-023a2fa789b7700ed32f8d78655c03b4b273d42b.tar.gz
cygnal-023a2fa789b7700ed32f8d78655c03b4b273d42b.tar.bz2
cygnal-023a2fa789b7700ed32f8d78655c03b4b273d42b.zip
* fhandler_socket.cc (fhandler_socket::recv_internal): Add MSG_WAITALL
handling. Use explicit flag values instead of MSG_WINMASK. (fhandler_socket::send_internal): Use explicit flag values instead of MSG_WINMASK. * include/cygwin/socket.h (MSG_WINMASK): Remove definition. (MSG_WAITALL): Define.
-rw-r--r--winsup/cygwin/ChangeLog9
-rw-r--r--winsup/cygwin/fhandler_socket.cc53
-rw-r--r--winsup/cygwin/include/cygwin/socket.h2
3 files changed, 54 insertions, 10 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 1968c9f2d..1cb0448a7 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,12 @@
+2007-11-28 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::recv_internal): Add MSG_WAITALL
+ handling. Use explicit flag values instead of MSG_WINMASK.
+ (fhandler_socket::send_internal): Use explicit flag values instead of
+ MSG_WINMASK.
+ * include/cygwin/socket.h (MSG_WINMASK): Remove definition.
+ (MSG_WAITALL): Define.
+
2007-11-27 Corinna Vinschen <corinna@vinschen.de>
* posix_ipc.cc (ipc_names): Rename max_len to prefix_len. Store
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index ba87ebe45..bebd44f79 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -1210,23 +1210,59 @@ fhandler_socket::recv_internal (WSABUF *wsabuf, DWORD wsacnt, DWORD flags,
struct sockaddr *from, int *fromlen)
{
ssize_t res = 0;
- DWORD ret = 0;
+ DWORD ret = 0, wret;
int evt_mask = FD_READ | ((flags & MSG_OOB) ? FD_OOB : 0);
- flags &= MSG_WINMASK;
+ bool waitall = (flags & MSG_WAITALL);
+ flags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE);
+ if (waitall)
+ {
+ if (get_socket_type () != SOCK_STREAM)
+ {
+ WSASetLastError (WSAEOPNOTSUPP);
+ set_winsock_errno ();
+ return SOCKET_ERROR;
+ }
+ if (is_nonblocking () || (flags & (MSG_OOB | MSG_PEEK)))
+ waitall = false;
+ }
+
/* Note: Don't call WSARecvFrom(MSG_PEEK) without actually having data
waiting in the buffers, otherwise the event handling gets messed up
for some reason. */
while (!(res = wait_for_events (evt_mask | FD_CLOSE))
|| saw_shutdown_read ())
{
- res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &ret,
+ res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &wret,
&flags, from, fromlen, NULL, NULL);
- if (!res || WSAGetLastError () != WSAEWOULDBLOCK)
+ if (!res)
+ {
+ ret += wret;
+ if (!waitall)
+ break;
+ while (wret && wsacnt)
+ {
+ if (wsabuf->len > wret)
+ {
+ wsabuf->len -= wret;
+ wsabuf->buf += wret;
+ wret = 0;
+ }
+ else
+ {
+ wret -= wsabuf->len;
+ ++wsabuf;
+ --wsacnt;
+ }
+ }
+ if (!wret)
+ break;
+ }
+ else if (WSAGetLastError () != WSAEWOULDBLOCK)
break;
}
- if (res == SOCKET_ERROR)
+ if (!ret && res == SOCKET_ERROR)
{
/* According to SUSv3, errno isn't set in that case and no error
condition is returned. */
@@ -1239,11 +1275,10 @@ fhandler_socket::recv_internal (WSABUF *wsabuf, DWORD wsacnt, DWORD flags,
return 0;
set_winsock_errno ();
+ return SOCKET_ERROR;
}
- else
- res = ret;
- return res;
+ return ret;
}
int
@@ -1317,7 +1352,7 @@ fhandler_socket::send_internal (struct _WSABUF *wsabuf, DWORD wsacnt, int flags,
do
{
if ((res = WSASendTo (get_socket (), wsabuf, wsacnt, &ret,
- flags & MSG_WINMASK, to, tolen, NULL, NULL))
+ flags & (MSG_OOB | MSG_DONTROUTE), to, tolen, NULL, NULL))
&& (err = WSAGetLastError ()) == WSAEWOULDBLOCK)
{
LOCK_EVENTS;
diff --git a/winsup/cygwin/include/cygwin/socket.h b/winsup/cygwin/include/cygwin/socket.h
index dd9cd3671..91b80dd13 100644
--- a/winsup/cygwin/include/cygwin/socket.h
+++ b/winsup/cygwin/include/cygwin/socket.h
@@ -189,7 +189,7 @@ struct OLD_msghdr
#define MSG_OOB 0x1 /* process out-of-band data */
#define MSG_PEEK 0x2 /* peek at incoming message */
#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-#define MSG_WINMASK 0x7 /* flags understood by WinSock calls */
+#define MSG_WAITALL 0x8 /* wait for all requested bytes */
#define MSG_NOSIGNAL 0x20 /* Don't raise SIGPIPE */
#define MSG_TRUNC 0x0100 /* Normal data truncated */
#define MSG_CTRUNC 0x0200 /* Control data truncated */