TRY 2: Socket resets randomly

Ryan Miller rmiller at auctionpay.com
Thu Sep 14 12:04:24 CDT 2006


ws2_32: Fixed bug with sockets randomly resetting due to GetLastError being reset by setsockopt in Windows, but not in Wine.  Also included is the associated test.

Ryan Miller (rmiller at auctionpay.com) & Zach Gorman (gormanjz at hotmail.com)

Index: dlls/ws2_32/socket.c
===================================================================
RCS file: /home/wine/wine/dlls/ws2_32/socket.c,v
retrieving revision 1.4
diff -u -r1.4 socket.c
--- dlls/ws2_32/socket.c        8 Sep 2006 10:16:19 -0000       1.4
+++ dlls/ws2_32/socket.c        8 Sep 2006 22:48:11 -0000
@@ -2660,6 +2660,11 @@
     TRACE("socket: %04x, level %d, name %d, ptr %p, len %d\n",
           s, level, optname, optval, optlen);

+    /* In Windows, if setsockopt succeeds, GetLastError() always returns zero.
+       The native wininet.dll expects this behavior, and does not always
+       check the return value of setsockopt() first.*/
+    SetLastError(0);
+
     /* SO_OPENTYPE does not require a valid socket handle. */
     if (level == WS_SOL_SOCKET && optname == WS_SO_OPENTYPE)
     {


Index: dlls/ws2_32/tests/sock.c
===================================================================
RCS file: /home/wine/wine/dlls/ws2_32/tests/sock.c,v
retrieving revision 1.2
diff -u -r1.2 sock.c
--- dlls/ws2_32/tests/sock.c    23 May 2006 12:49:01 -0000      1.2
+++ dlls/ws2_32/tests/sock.c    8 Sep 2006 22:48:12 -0000
@@ -1410,6 +1410,27 @@

 }

+static void test_setsockopt_last_error() {
+    SOCKET s;
+    BOOL bKeepAlive=0;
+    struct sockaddr_in addr;
+    struct timeval select_timeout;
+
+    select_timeout.tv_sec=5;
+    select_timeout.tv_usec=0;
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = inet_addr(SERVERIP);
+    addr.sin_port = htons(SERVERPORT);
+
+    s = socket(AF_INET, SOCK_STREAM, 0);
+    do_bind(s, (struct sockaddr *)&addr, sizeof(addr));
+
+    SetLastError(1);
+    setsockopt(s,SOL_SOCKET, SO_KEEPALIVE, (char *)&bKeepAlive, sizeof(bKeepAlive));
+    ok( GetLastError()==0, "GetLastError() was not cleared by setsockopt\n");
+    closesocket(s);
+}
+
 /**************** Main program  ***************/

 START_TEST( sock )
@@ -1438,6 +1459,8 @@
     test_WSAStringToAddressW();

     test_select();
-
+
+    test_setsockopt_last_error();
+
     Exit();
 }






More information about the wine-patches mailing list