4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-19 04:49:25 +08:00

Ensure that send() interrupted by a signal returns sucessfully

When SA_RESTART is not set on a socket, a blocking send() that is
interrupted mid-transition by a signal should return success (and
report just how many bytes were actually transmitted).

The err variable used here was not always guaranteed to be set
correctly in the loop, so better to just remove it and call
WSAGetLastError() explicitly.
This commit is contained in:
Erik M. Bray 2017-06-15 15:30:08 +02:00 committed by Corinna Vinschen
parent a5cc86ba13
commit 5ca286666a

View File

@ -1769,7 +1769,7 @@ inline ssize_t
fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags) fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
{ {
ssize_t res = 0; ssize_t res = 0;
DWORD ret = 0, err = 0, sum = 0; DWORD ret = 0, sum = 0;
WSABUF out_buf[wsamsg->dwBufferCount]; WSABUF out_buf[wsamsg->dwBufferCount];
bool use_sendmsg = false; bool use_sendmsg = false;
DWORD wait_flags = flags & MSG_DONTWAIT; DWORD wait_flags = flags & MSG_DONTWAIT;
@ -1830,14 +1830,14 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
res = WSASendTo (get_socket (), wsamsg->lpBuffers, res = WSASendTo (get_socket (), wsamsg->lpBuffers,
wsamsg->dwBufferCount, &ret, flags, wsamsg->dwBufferCount, &ret, flags,
wsamsg->name, wsamsg->namelen, NULL, NULL); wsamsg->name, wsamsg->namelen, NULL, NULL);
if (res && (err = WSAGetLastError ()) == WSAEWOULDBLOCK) if (res && (WSAGetLastError () == WSAEWOULDBLOCK))
{ {
LOCK_EVENTS; LOCK_EVENTS;
wsock_events->events &= ~FD_WRITE; wsock_events->events &= ~FD_WRITE;
UNLOCK_EVENTS; UNLOCK_EVENTS;
} }
} }
while (res && err == WSAEWOULDBLOCK while (res && (WSAGetLastError () == WSAEWOULDBLOCK)
&& !(res = wait_for_events (FD_WRITE | FD_CLOSE, wait_flags))); && !(res = wait_for_events (FD_WRITE | FD_CLOSE, wait_flags)));
if (!res) if (!res)
@ -1851,7 +1851,7 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
if (get_socket_type () != SOCK_STREAM || ret < out_len) if (get_socket_type () != SOCK_STREAM || ret < out_len)
break; break;
} }
else if (is_nonblocking () || err != WSAEWOULDBLOCK) else if (is_nonblocking () || WSAGetLastError() != WSAEWOULDBLOCK)
break; break;
} }