* 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.
This commit is contained in:
Corinna Vinschen 2007-11-28 15:54:17 +00:00
parent 02cb1fd853
commit 023a2fa789
3 changed files with 54 additions and 10 deletions

View File

@ -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

View File

@ -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;

View File

@ -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 */