[Wine-patches] [eter-2.1] ws2_32: Make _is_blocking() return server error code, so that callers can act appropriately. (eterbug #9150)
Dmitry Timoshkov
dtimoshkov на etersoft.ru
Вт Мар 26 08:10:44 MSK 2013
(cherry picked from commit c09c82b25a3c95e79f23f22571fe9a63b38b824c)
---
dlls/ws2_32/socket.c | 51 ++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 40 insertions(+), 11 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index fbec213..09dd5ff 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -807,19 +807,19 @@ static void _enable_event( HANDLE s, unsigned int event,
SERVER_END_REQ;
}
-static int _is_blocking(SOCKET s)
+static NTSTATUS _is_blocking(SOCKET s, BOOL *ret)
{
- int ret;
+ NTSTATUS status;
SERVER_START_REQ( get_socket_event )
{
req->handle = wine_server_obj_handle( SOCKET2HANDLE(s) );
req->service = FALSE;
req->c_event = 0;
- wine_server_call( req );
- ret = (reply->state & FD_WINE_NONBLOCKING) == 0;
+ status = wine_server_call( req );
+ *ret = (reply->state & FD_WINE_NONBLOCKING) == 0;
}
SERVER_END_REQ;
- return ret;
+ return status;
}
static unsigned int _get_sock_mask(SOCKET s)
@@ -839,9 +839,10 @@ static unsigned int _get_sock_mask(SOCKET s)
static void _sync_sock_state(SOCKET s)
{
+ BOOL dummy;
/* do a dummy wineserver request in order to let
the wineserver run through its select loop once */
- (void)_is_blocking(s);
+ (void)_is_blocking(s, &dummy);
}
static int _get_sock_error(SOCKET s, unsigned int bit)
@@ -1991,7 +1992,12 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr,
BOOL is_blocking;
TRACE("socket %04lx\n", s );
- is_blocking = _is_blocking(s);
+ status = _is_blocking(s, &is_blocking);
+ if (status)
+ {
+ set_error(status);
+ return INVALID_SOCKET;
+ }
do {
/* try accepting first (if there is a deferred connection) */
@@ -2427,6 +2433,8 @@ int WINAPI WS_connect(SOCKET s, const struct WS_sockaddr* name, int namelen)
if (fd != -1)
{
+ NTSTATUS status;
+ BOOL is_blocking;
int ret = do_connect(fd, name, namelen);
if (ret == 0)
goto connect_success;
@@ -2437,7 +2445,14 @@ int WINAPI WS_connect(SOCKET s, const struct WS_sockaddr* name, int namelen)
_enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE,
FD_CONNECT,
FD_WINE_CONNECTED|FD_WINE_LISTENING);
- if (_is_blocking(s))
+ status = _is_blocking( s, &is_blocking );
+ if (status)
+ {
+ release_sock_fd( s, fd );
+ set_error( status );
+ return SOCKET_ERROR;
+ }
+ if (is_blocking)
{
int result;
/* block here */
@@ -4050,6 +4065,7 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
DWORD timeout_start;
ULONG_PTR cvalue = (lpOverlapped && ((ULONG_PTR)lpOverlapped->hEvent & 1) == 0) ? (ULONG_PTR)lpOverlapped : 0;
DWORD bytes_sent;
+ BOOL is_blocking;
TRACE("socket %04lx, wsabuf %p, nbufs %d, flags %d, to %p, tolen %d, ovl %p, func %p\n",
s, lpBuffers, dwBufferCount, dwFlags,
@@ -4156,7 +4172,13 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
struct pollfd pfd;
int timeout = 50;
- if ( _is_blocking(s) )
+ if ((err = _is_blocking( s, &is_blocking )))
+ {
+ err = NtStatusToWSAError( err );
+ goto error;
+ }
+
+ if ( is_blocking )
timeout = GET_SNDTIMEO(fd);
if (timeout != -1)
@@ -4170,7 +4192,7 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
if (!timeout || check_eterbug3421() || !poll( &pfd, 1, timeout ))
{
- if ( !_is_blocking(s) )
+ if ( !is_blocking )
{
_enable_event( SOCKET2HANDLE(s), FD_WRITE, 0, 0 );
if (n >= 0) break;
@@ -5935,6 +5957,7 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
unsigned int i, options;
int n, fd, err;
struct ws2_async *wsa;
+ BOOL is_blocking;
DWORD timeout_start = GetTickCount();
ULONG_PTR cvalue = (lpOverlapped && ((ULONG_PTR)lpOverlapped->hEvent & 1) == 0) ? (ULONG_PTR)lpOverlapped : 0;
@@ -6038,7 +6061,13 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
if (n != -1) break;
- if ( _is_blocking(s) )
+ if ((err = _is_blocking( s, &is_blocking )))
+ {
+ err = NtStatusToWSAError( err );
+ goto error;
+ }
+
+ if ( is_blocking )
{
struct pollfd pfd;
int timeout = GET_RCVTIMEO(fd);
--
1.8.2
Подробная информация о списке рассылки Wine-patches