Bruno Jesus : ws2_32: SO_OOBINLINE sockets must always return TRUE to SIOCATMARK request.

Alexandre Julliard julliard at winehq.org
Tue Sep 13 12:18:10 CDT 2011


Module: wine
Branch: master
Commit: fd7b94bcd2b5d8ee48f329ec3705da9ef3fcf5ce
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fd7b94bcd2b5d8ee48f329ec3705da9ef3fcf5ce

Author: Bruno Jesus <00cpxxx at gmail.com>
Date:   Tue Sep 13 08:07:00 2011 -0400

ws2_32: SO_OOBINLINE sockets must always return TRUE to SIOCATMARK request.

---

 dlls/ws2_32/socket.c     |   21 +++++++++++++++++++--
 dlls/ws2_32/tests/sock.c |   23 ++++++++++++++++++++---
 2 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index bfe34ce..b6d17ff 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -3099,17 +3099,34 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
         break;
 
     case WS_FIONREAD:
+    {
+        if (out_size != sizeof(WS_u_long) || IS_INTRESOURCE(out_buff))
+        {
+            WSASetLastError(WSAEFAULT);
+            return SOCKET_ERROR;
+        }
+        if ((fd = get_sock_fd( s, 0, NULL )) == -1) return SOCKET_ERROR;
+        if (ioctl(fd, FIONREAD, out_buff ) == -1)
+            status = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
+        release_sock_fd( s, fd );
+        break;
+    }
+
     case WS_SIOCATMARK:
     {
-        int cmd = code == WS_FIONREAD ? FIONREAD : SIOCATMARK;
+        unsigned int oob = 0, oobsize = sizeof(int), atmark = 0;
         if (out_size != sizeof(WS_u_long) || IS_INTRESOURCE(out_buff))
         {
             WSASetLastError(WSAEFAULT);
             return SOCKET_ERROR;
         }
         if ((fd = get_sock_fd( s, 0, NULL )) == -1) return SOCKET_ERROR;
-        if (ioctl(fd, cmd, out_buff ) == -1)
+        /* SO_OOBINLINE sockets must always return TRUE to SIOCATMARK */
+        if ((getsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &oob, &oobsize ) == -1)
+           || (!oob && ioctl(fd, SIOCATMARK, &atmark ) == -1))
             status = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
+        else
+            (*(WS_u_long *) out_buff) = oob | atmark;
         release_sock_fd( s, fd );
         break;
     }
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 3766186..326b77d 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -2939,7 +2939,7 @@ static void test_ioctlsocket(void)
 {
     SOCKET sock;
     struct tcp_keepalive kalive;
-    int ret;
+    int ret, optval;
     static const LONG cmds[] = {FIONBIO, FIONREAD, SIOCATMARK};
     UINT i;
     u_long arg = 0;
@@ -2965,8 +2965,25 @@ static void test_ioctlsocket(void)
      * that normal(not urgent) data returns a non-zero value for SIOCATMARK. */
 
     ret = ioctlsocket(sock, SIOCATMARK, &arg);
-    if(ret != SOCKET_ERROR)
-        todo_wine ok(arg, "expected a non-zero value\n");
+    ok(ret != SOCKET_ERROR, "ioctlsocket failed unexpectedly\n");
+    todo_wine ok(arg, "SIOCATMARK expected a non-zero value\n");
+
+    /* when SO_OOBINLINE is set SIOCATMARK must always return TRUE */
+    optval = 1;
+    ret = setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, (void *)&optval, sizeof(optval));
+    ok(ret != SOCKET_ERROR, "setsockopt failed unexpectedly\n");
+    arg = 0;
+    ret = ioctlsocket(sock, SIOCATMARK, &arg);
+    ok(ret != SOCKET_ERROR, "ioctlsocket failed unexpectedly\n");
+    ok(arg, "SIOCATMARK expected a non-zero value\n");
+
+    /* disable SO_OOBINLINE and get the same old bahavior */
+    optval = 0;
+    ret = setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, (void *)&optval, sizeof(optval));
+    ok(ret != SOCKET_ERROR, "setsockopt failed unexpectedly\n");
+    arg = 0;
+    ret = ioctlsocket(sock, SIOCATMARK, &arg);
+    todo_wine ok(arg, "SIOCATMARK expected a non-zero value\n");
 
     ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &arg, 0, NULL, 0, &arg, NULL, NULL);
     ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");




More information about the wine-cvs mailing list