Rather than WSAEOPNOTSUPP.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 2 +- dlls/ws2_32/tests/sock.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 79085cf0c2a..478ae960541 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3536,7 +3536,7 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID }
FIXME("SIO_GET_EXTENSION_FUNCTION_POINTER %s: stub\n", debugstr_guid(in_buff)); - SetLastError( WSAEOPNOTSUPP ); + SetLastError( WSAEINVAL ); return -1; } case WS_SIO_KEEPALIVE_VALS: diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index c0b1abcaaa5..ec138fcf29a 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4258,7 +4258,7 @@ static void test_get_extension_func(void) ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &bogus_guid, sizeof(GUID), &func, sizeof(func), &size, &overlapped, NULL); ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError()); + ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError()); ok(size == 0xdeadbeef, "got size %u\n", size); ok(overlapped.Internal == 0xdeadbeef, "got status %#x\n", (NTSTATUS)overlapped.Internal); ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/unix/socket.c | 42 ++++++++++++++++++++++++++++++++++++++++ include/wine/afd.h | 1 + 2 files changed, 43 insertions(+)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index cfc5780b082..16df04b6cb1 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -25,6 +25,9 @@ #include "config.h" #include <errno.h> #include <unistd.h> +#ifdef HAVE_SYS_IOCTL_H +# include <sys/ioctl.h> +#endif #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif @@ -1274,6 +1277,45 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc status = sock_poll( handle, event, apc, apc_user, io, in_buffer, in_size, out_buffer, out_size ); break;
+ case IOCTL_AFD_WINE_FIONREAD: + { + int value, ret; + + if (out_size < sizeof(int)) + { + status = STATUS_BUFFER_TOO_SMALL; + break; + } + + if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))) + return status; + +#ifdef linux + { + socklen_t len = sizeof(value); + + /* FIONREAD on a listening socket always fails (see tcp(7)). */ + if (!getsockopt( fd, SOL_SOCKET, SO_ACCEPTCONN, &value, &len ) && value) + { + *(int *)out_buffer = 0; + status = STATUS_SUCCESS; + complete_async( handle, event, apc, apc_user, io, status, 0 ); + break; + } + } +#endif + + if ((ret = ioctl( fd, FIONREAD, &value )) < 0) + { + status = sock_errno_to_status( errno ); + break; + } + *(int *)out_buffer = value; + status = STATUS_SUCCESS; + complete_async( handle, event, apc, apc_user, io, status, 0 ); + break; + } + default: { if ((code >> 16) == FILE_DEVICE_NETWORK) diff --git a/include/wine/afd.h b/include/wine/afd.h index 77801b1fbe3..0c19c8e0f58 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -98,6 +98,7 @@ struct afd_poll_params #define IOCTL_AFD_WINE_ADDRESS_LIST_CHANGE CTL_CODE(FILE_DEVICE_NETWORK, 208, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_FIONBIO CTL_CODE(FILE_DEVICE_NETWORK, 209, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_COMPLETE_ASYNC CTL_CODE(FILE_DEVICE_NETWORK, 210, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_WINE_FIONREAD CTL_CODE(FILE_DEVICE_NETWORK, 211, METHOD_BUFFERED, FILE_ANY_ACCESS)
struct afd_create_params {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=91665
Your paranoid android.
=== debiant2 (32 bit WoW report) ===
ntdll: om.c:2307: Test failed: got 89
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 27 ++++++--------------------- dlls/ws2_32/tests/sock.c | 21 +++++++++------------ 2 files changed, 15 insertions(+), 33 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 478ae960541..e9df9f579f2 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3359,28 +3359,13 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
case WS_FIONREAD: { -#if defined(linux) - int listening = 0; - socklen_t len = sizeof(listening); -#endif - if (out_size != sizeof(WS_u_long) || IS_INTRESOURCE(out_buff)) - { - SetLastError(WSAEFAULT); - return SOCKET_ERROR; - } - if ((fd = get_sock_fd( s, 0, NULL )) == -1) return SOCKET_ERROR; + DWORD ret;
-#if defined(linux) - /* On Linux, FIONREAD on listening socket always fails (see tcp(7)). - However, it succeeds on native. */ - if (!getsockopt( fd, SOL_SOCKET, SO_ACCEPTCONN, &listening, &len ) && listening) - (*(WS_u_long *) out_buff) = 0; - else -#endif - if (ioctl(fd, FIONREAD, out_buff ) == -1) - status = wsaErrno(); - release_sock_fd( s, fd ); - break; + ret = server_ioctl_sock( s, IOCTL_AFD_WINE_FIONREAD, in_buff, in_size, + out_buff, out_size, ret_size, overlapped, completion ); + SetLastError( ret ); + if (!ret) *ret_size = sizeof(WS_u_long); + return ret ? -1 : 0; }
case WS_SIOCATMARK: diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index ec138fcf29a..c251f31f382 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -3667,7 +3667,7 @@ static void check_fionread_siocatmark_(int line, SOCKET s, unsigned int normal, WSASetLastError(0xdeadbeef); ret = WSAIoctl(s, FIONREAD, NULL, 0, &value, sizeof(value), &size, NULL, NULL); ok_(__FILE__, line)(!ret, "expected success\n"); - todo_wine ok_(__FILE__, line)(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); + ok_(__FILE__, line)(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); todo_wine_if (todo_normal) ok_(__FILE__, line)(value == normal, "FIONBIO returned %u\n", value);
value = 0xdeadbeef; @@ -3746,9 +3746,9 @@ static void test_fionread_siocatmark(void) overlapped.InternalHigh = 0xdeadbeef; ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value), &size, &overlapped, NULL); ok(!ret, "expected success\n"); - todo_wine ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); + ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); ok(!value, "got %u\n", value); - todo_wine ok(size == sizeof(value), "got size %u\n", size); + ok(size == sizeof(value), "got size %u\n", size); ok(!overlapped.Internal, "got status %#x\n", (NTSTATUS)overlapped.Internal); ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
@@ -3868,17 +3868,14 @@ static void test_fionread_siocatmark(void) size = 0xdeadbeef; ret = WSAIoctl(server, FIONREAD, NULL, 0, &value, sizeof(value), &size, &overlapped, socket_apc); ok(!ret, "expected success\n"); - todo_wine ok(size == sizeof(value), "got size %u\n", size); + ok(size == sizeof(value), "got size %u\n", size);
ret = SleepEx(0, TRUE); - todo_wine ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret); - if (ret == WAIT_IO_COMPLETION) - { - ok(apc_count == 1, "APC was called %u times\n", apc_count); - ok(!apc_error, "got APC error %u\n", apc_error); - ok(!apc_size, "got APC size %u\n", apc_size); - ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped); - } + ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret); + ok(apc_count == 1, "APC was called %u times\n", apc_count); + ok(!apc_error, "got APC error %u\n", apc_error); + ok(!apc_size, "got APC size %u\n", apc_size); + ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
apc_count = 0; size = 0xdeadbeef;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/unix/socket.c | 39 +++++++++++++++++++++++++++++++++++++++ include/wine/afd.h | 1 + 2 files changed, 40 insertions(+)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index 16df04b6cb1..c10a48b3008 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -1316,6 +1316,45 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc break; }
+ case IOCTL_AFD_WINE_SIOCATMARK: + { + int value, ret; + socklen_t len = sizeof(value); + + if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))) + return status; + + if (out_size < sizeof(int)) + { + status = STATUS_BUFFER_TOO_SMALL; + break; + } + + if (getsockopt( fd, SOL_SOCKET, SO_OOBINLINE, &value, &len ) < 0) + { + status = sock_errno_to_status( errno ); + break; + } + + if (value) + { + *(int *)out_buffer = TRUE; + } + else + { + if ((ret = ioctl( fd, SIOCATMARK, &value )) < 0) + { + status = sock_errno_to_status( errno ); + break; + } + /* windows is reversed with respect to unix */ + *(int *)out_buffer = !value; + } + status = STATUS_SUCCESS; + complete_async( handle, event, apc, apc_user, io, status, 0 ); + break; + } + default: { if ((code >> 16) == FILE_DEVICE_NETWORK) diff --git a/include/wine/afd.h b/include/wine/afd.h index 0c19c8e0f58..2b4c39e7a86 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -99,6 +99,7 @@ struct afd_poll_params #define IOCTL_AFD_WINE_FIONBIO CTL_CODE(FILE_DEVICE_NETWORK, 209, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_COMPLETE_ASYNC CTL_CODE(FILE_DEVICE_NETWORK, 210, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_FIONREAD CTL_CODE(FILE_DEVICE_NETWORK, 211, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_WINE_SIOCATMARK CTL_CODE(FILE_DEVICE_NETWORK, 212, METHOD_BUFFERED, FILE_ANY_ACCESS)
struct afd_create_params {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 28 ++++++---------------------- dlls/ws2_32/tests/sock.c | 21 +++++++++------------ 2 files changed, 15 insertions(+), 34 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index e9df9f579f2..bfe5ab186ee 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3370,29 +3370,13 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
case WS_SIOCATMARK: { - unsigned int oob = 0, atmark = 0; - socklen_t oobsize = sizeof(int); - if (out_size != sizeof(WS_u_long) || IS_INTRESOURCE(out_buff)) - { - SetLastError(WSAEFAULT); - return SOCKET_ERROR; - } - if ((fd = get_sock_fd( s, 0, NULL )) == -1) return SOCKET_ERROR; - /* 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 = wsaErrno(); - else - { - /* The SIOCATMARK value read from ioctl() is reversed - * because BSD returns TRUE if it's in the OOB mark - * while Windows returns TRUE if there are NO OOB bytes. - */ - (*(WS_u_long *) out_buff) = oob || !atmark; - } + DWORD ret;
- release_sock_fd( s, fd ); - break; + ret = server_ioctl_sock( s, IOCTL_AFD_WINE_SIOCATMARK, in_buff, in_size, + out_buff, out_size, ret_size, overlapped, completion ); + SetLastError( ret ); + if (!ret) *ret_size = sizeof(WS_u_long); + return ret ? -1 : 0; }
case WS_FIOASYNC: diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index c251f31f382..f165742fe45 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -3674,7 +3674,7 @@ static void check_fionread_siocatmark_(int line, SOCKET s, unsigned int normal, WSASetLastError(0xdeadbeef); ret = WSAIoctl(s, SIOCATMARK, NULL, 0, &value, sizeof(value), &size, NULL, NULL); ok_(__FILE__, line)(!ret, "expected success\n"); - todo_wine ok_(__FILE__, line)(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); + ok_(__FILE__, line)(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); todo_wine_if (todo_oob) ok_(__FILE__, line)(value == oob, "SIOCATMARK returned %u\n", value); }
@@ -3765,9 +3765,9 @@ static void test_fionread_siocatmark(void) overlapped.InternalHigh = 0xdeadbeef; ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value), &size, &overlapped, NULL); ok(!ret, "expected success\n"); - todo_wine ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); + ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError()); ok(value == TRUE, "got %u\n", value); - todo_wine ok(size == sizeof(value), "got size %u\n", size); + ok(size == sizeof(value), "got size %u\n", size); ok(!overlapped.Internal, "got status %#x\n", (NTSTATUS)overlapped.Internal); ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
@@ -3881,17 +3881,14 @@ static void test_fionread_siocatmark(void) size = 0xdeadbeef; ret = WSAIoctl(server, SIOCATMARK, NULL, 0, &value, sizeof(value), &size, &overlapped, socket_apc); ok(!ret, "expected success\n"); - todo_wine ok(size == sizeof(value), "got size %u\n", size); + ok(size == sizeof(value), "got size %u\n", size);
ret = SleepEx(0, TRUE); - todo_wine ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret); - if (ret == WAIT_IO_COMPLETION) - { - ok(apc_count == 1, "APC was called %u times\n", apc_count); - ok(!apc_error, "got APC error %u\n", apc_error); - ok(!apc_size, "got APC size %u\n", apc_size); - ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped); - } + ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret); + ok(apc_count == 1, "APC was called %u times\n", apc_count); + ok(!apc_error, "got APC error %u\n", apc_error); + ok(!apc_size, "got APC size %u\n", apc_size); + ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
closesocket(server); }