[3/3] ws2_32: Add WSAPoll() implementation
Bruno Jesus
00cpxxx at gmail.com
Fri May 22 20:43:11 CDT 2015
Still some todos to fix but fixes https://bugs.winehq.org/show_bug.cgi?id=38600
-------------- next part --------------
---
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
More information about the wine-patches
mailing list