From: Bruno Jesus <00cpxxx@gmail.com> Subject: [3/3] ws2_32: Add WSAPoll() implementation Message-Id: Date: Fri, 22 May 2015 22:43:11 -0300 Still some todos to fix but fixes https://bugs.winehq.org/show_bug.cgi?id=38600 --- dlls/ws2_32/socket.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ dlls/ws2_32/tests/sock.c | 4 +++ dlls/ws2_32/ws2_32.spec | 1 + 3 files changed, 99 insertions(+) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index fdf68a3..68e6d54 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -740,6 +740,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 @@ -1374,6 +1385,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 @@ -4886,6 +4931,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 3d584f2..1ed1aba 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -6426,6 +6426,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); @@ -6444,6 +6445,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; @@ -6465,6 +6467,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); @@ -6488,6 +6491,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 f7c6c2d..a4e0b6b 100644 --- a/dlls/ws2_32/ws2_32.spec +++ b/dlls/ws2_32/ws2_32.spec @@ -89,6 +89,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) -- 2.1.4