[Wine-patches] [eter-2.0.0] ws2_32: Make _is_blocking() return server error code, so that callers can act appropriately. (eterbug #9150)

Dmitry Timoshkov dtimoshkov на etersoft.ru
Вт Мар 26 08:32:32 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 e436e82..ad1351b 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -774,19 +774,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)
@@ -806,9 +806,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)
@@ -1958,7 +1959,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) */
@@ -2314,6 +2320,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;
@@ -2324,7 +2332,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 */
@@ -3929,6 +3944,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,
@@ -4037,7 +4053,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)
@@ -4051,7 +4073,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;
@@ -5789,6 +5811,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;
 
@@ -5892,7 +5915,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