Bruno Jesus : ws2_32: Add WSAPoll() implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Dec 22 14:06:51 CST 2015


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

Author: Bruno Jesus <00cpxxx at gmail.com>
Date:   Tue Dec 22 21:15:41 2015 +0800

ws2_32: Add WSAPoll() implementation.

Signed-off-by: Bruno Jesus <00cpxxx at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ws2_32/socket.c     | 94 ++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/ws2_32/tests/sock.c |  4 +++
 dlls/ws2_32/ws2_32.spec  |  1 +
 include/winsock2.h       |  4 +--
 4 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index d31f0b4..f62c9cd 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -773,6 +773,17 @@ static const int ws_eai_map[][2] =
     { 0, 0 }
 };
 
+static const int ws_poll_map[][2] =
+{
+    MAP_OPTION( POLLERR ),
+    MAP_OPTION( POLLHUP ),
+    MAP_OPTION( POLLNVAL ),
+    MAP_OPTION( POLLWRNORM ),
+    MAP_OPTION( POLLWRBAND ),
+    MAP_OPTION( POLLRDNORM ),
+    { WS_POLLRDBAND, POLLPRI }
+};
+
 static const char magic_loopback_addr[] = {127, 12, 34, 56};
 
 #ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
@@ -1415,6 +1426,40 @@ convert_socktype_u2w(int unixsocktype) {
     return -1;
 }
 
+static int convert_poll_w2u(int events)
+{
+    int i, ret;
+    for (i = ret = 0; events && i < sizeof(ws_poll_map) / sizeof(ws_poll_map[0]); i++)
+    {
+        if (ws_poll_map[i][0] & events)
+        {
+            ret |= ws_poll_map[i][1];
+            events &= ~ws_poll_map[i][0];
+        }
+    }
+
+    if (events)
+        FIXME("Unsupported WSAPoll() flags 0x%x\n", events);
+    return ret;
+}
+
+static int convert_poll_u2w(int events)
+{
+    int i, ret;
+    for (i = ret = 0; events && i < sizeof(ws_poll_map) / sizeof(ws_poll_map[0]); i++)
+    {
+        if (ws_poll_map[i][1] & events)
+        {
+            ret |= ws_poll_map[i][0];
+            events &= ~ws_poll_map[i][1];
+        }
+    }
+
+    if (events)
+        FIXME("Unsupported poll() flags 0x%x\n", events);
+    return ret;
+}
+
 static int set_ipx_packettype(int sock, int ptype)
 {
 #ifdef HAS_IPX
@@ -5227,6 +5272,55 @@ int WINAPI WS_select(int nfds, WS_fd_set *ws_readfds,
     return ret;
 }
 
+/***********************************************************************
+ *     WSAPoll
+ */
+int WINAPI WSAPoll(WSAPOLLFD *wfds, ULONG count, int timeout)
+{
+    int i, ret;
+    struct pollfd *ufds;
+
+    if (!count)
+    {
+        SetLastError(WSAEINVAL);
+        return SOCKET_ERROR;
+    }
+    if (!wfds)
+    {
+        SetLastError(WSAEFAULT);
+        return SOCKET_ERROR;
+    }
+
+    if (!(ufds = HeapAlloc(GetProcessHeap(), 0, count * sizeof(ufds[0]))))
+    {
+        SetLastError(WSAENOBUFS);
+        return SOCKET_ERROR;
+    }
+
+    for (i = 0; i < count; i++)
+    {
+        ufds[i].fd = get_sock_fd(wfds[i].fd, 0, NULL);
+        ufds[i].events = convert_poll_w2u(wfds[i].events);
+        ufds[i].revents = 0;
+    }
+
+    ret = do_poll(ufds, count, timeout);
+
+    for (i = 0; i < count; i++)
+    {
+        if (ufds[i].fd != -1)
+        {
+            release_sock_fd(wfds[i].fd, ufds[i].fd);
+            wfds[i].revents = convert_poll_u2w(ufds[i].revents);
+        }
+        else
+            wfds[i].revents = WS_POLLNVAL;
+    }
+
+    HeapFree(GetProcessHeap(), 0, ufds);
+    return ret;
+}
+
 /* helper to send completion messages for client-only i/o operation case */
 static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus,
                               ULONG Information )
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 00fac77..aeb7a62 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -6634,6 +6634,7 @@ static void test_WSAPoll(void)
     POLL_SET(fdWrite, POLLIN);
     ret = pWSAPoll(fds, ix, poll_timeout);
     ok(ret == 1, "expected 1, got %d\n", ret);
+todo_wine
     ok(POLL_ISSET(fdWrite, POLLHUP), "fdWrite socket events incorrect\n");
     ret = recv(fdWrite, tmp_buf, sizeof(tmp_buf), 0);
     ok(ret == 0, "expected 0, got %d\n", ret);
@@ -6652,6 +6653,7 @@ static void test_WSAPoll(void)
     POLL_SET(fdWrite, POLLIN | POLLOUT);
     poll_timeout = 2000;
     ret = pWSAPoll(fds, ix, poll_timeout);
+todo_wine
     ok(ret == 0, "expected 0, got %d\n", ret);
     len = sizeof(id);
     id = 0xdeadbeef;
@@ -6673,6 +6675,7 @@ static void test_WSAPoll(void)
     POLL_SET(fdWrite, POLLIN | POLLOUT);
     ret = pWSAPoll(fds, ix, poll_timeout);
     ok(ret == 1, "expected 1, got %d\n", ret);
+todo_wine
     ok(POLL_ISSET(fdWrite, POLLWRNORM | POLLHUP) || broken(POLL_ISSET(fdWrite, POLLWRNORM)) /* <= 2008 */,
        "fdWrite socket events incorrect\n");
     closesocket(fdWrite);
@@ -6696,6 +6699,7 @@ static void test_WSAPoll(void)
     POLL_SET(fdWrite, POLLIN);
     ret = pWSAPoll(fds, ix, poll_timeout);
     ok(ret == 1, "expected 1, got %d\n", ret);
+todo_wine
     ok(POLL_ISSET(fdWrite, POLLNVAL), "fdWrite socket events incorrect\n");
     WaitForSingleObject (thread_handle, 1000);
     closesocket(fdRead);
diff --git a/dlls/ws2_32/ws2_32.spec b/dlls/ws2_32/ws2_32.spec
index 6de888f..7625f38 100644
--- a/dlls/ws2_32/ws2_32.spec
+++ b/dlls/ws2_32/ws2_32.spec
@@ -91,6 +91,7 @@
 @ stdcall WSANSPIoctl(ptr long ptr long ptr long ptr ptr)
 @ stdcall WSANtohl(long long ptr)
 @ stdcall WSANtohs(long long ptr)
+@ stdcall WSAPoll(ptr long long)
 @ stdcall WSAProviderConfigChange(ptr ptr ptr)
 @ stdcall WSARecv(long ptr long ptr ptr ptr ptr)
 @ stdcall WSARecvDisconnect(long ptr)
diff --git a/include/winsock2.h b/include/winsock2.h
index 461b90c..24f0ea3 100644
--- a/include/winsock2.h
+++ b/include/winsock2.h
@@ -113,8 +113,8 @@ extern "C" {
 #define SD_BOTH                    0x02
 
 /* Constants for WSAPoll() */
-#ifndef __WINE_WINE_PORT_H
 #ifndef USE_WS_PREFIX
+#ifndef __WINE_WINE_PORT_H
 #define POLLERR                    0x0001
 #define POLLHUP                    0x0002
 #define POLLNVAL                   0x0004
@@ -125,6 +125,7 @@ extern "C" {
 #define POLLPRI                    0x0400
 #define POLLIN                     (POLLRDNORM|POLLRDBAND)
 #define POLLOUT                    (POLLWRNORM)
+#endif
 #else
 #define WS_POLLERR                 0x0001
 #define WS_POLLHUP                 0x0002
@@ -137,7 +138,6 @@ extern "C" {
 #define WS_POLLIN                  (WS_POLLRDNORM|WS_POLLRDBAND)
 #define WS_POLLOUT                 (WS_POLLWRNORM)
 #endif
-#endif
 
 /* Constants for WSAIoctl() */
 #ifdef USE_WS_PREFIX




More information about the wine-cvs mailing list