Signed-off-by: Zebediah Figura z.figura12@gmail.com --- include/wine/afd.h | 1 + server/sock.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+)
diff --git a/include/wine/afd.h b/include/wine/afd.h index 6370e00539f..0ccd248e614 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -162,6 +162,7 @@ struct afd_get_events_params #define IOCTL_AFD_WINE_GET_SO_ACCEPTCONN CTL_CODE(FILE_DEVICE_NETWORK, 219, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_SO_BROADCAST CTL_CODE(FILE_DEVICE_NETWORK, 220, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_SET_SO_BROADCAST CTL_CODE(FILE_DEVICE_NETWORK, 221, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_WINE_GET_SO_ERROR CTL_CODE(FILE_DEVICE_NETWORK, 222, METHOD_BUFFERED, FILE_ANY_ACCESS)
struct afd_create_params { diff --git a/server/sock.c b/server/sock.c index 71f22845827..f614bf5feaa 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2546,6 +2546,40 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) return 1; }
+ case IOCTL_AFD_WINE_GET_SO_ERROR: + { + int error; + socklen_t len = sizeof(error); + unsigned int i; + + if (get_reply_max_size() < sizeof(error)) + { + set_error( STATUS_BUFFER_TOO_SMALL ); + return 0; + } + + if (getsockopt( unix_fd, SOL_SOCKET, SO_ERROR, (char *)&error, &len ) < 0) + { + set_error( sock_get_ntstatus( errno ) ); + return 0; + } + + if (!error) + { + for (i = 0; i < ARRAY_SIZE( sock->errors ); ++i) + { + if (sock->errors[i]) + { + error = sock->errors[i]; + break; + } + } + } + + set_reply_data( &error, sizeof(error) ); + return 1; + } + default: set_error( STATUS_NOT_SUPPORTED ); return 0;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 41 +--------------------------------------- dlls/ws2_32/tests/sock.c | 2 -- 2 files changed, 1 insertion(+), 42 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index ab111f726a9..b183b85b0b3 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -694,19 +694,6 @@ static inline void release_sock_fd( SOCKET s, int fd ) close( fd ); }
-static void _get_sock_errors(SOCKET s, int *events) -{ - SERVER_START_REQ( get_socket_event ) - { - req->handle = wine_server_obj_handle( SOCKET2HANDLE(s) ); - req->service = FALSE; - req->c_event = 0; - wine_server_set_reply( req, events, sizeof(int) * FD_MAX_EVENTS ); - wine_server_call( req ); - } - SERVER_END_REQ; -} - static int _get_fd_type(int fd) { int sock_type = -1; @@ -2236,33 +2223,7 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, return 0;
case WS_SO_ERROR: - { - if ( (fd = get_sock_fd( s, 0, NULL )) == -1) - return SOCKET_ERROR; - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, optval, (socklen_t *)optlen) != 0 ) - { - SetLastError(wsaErrno()); - ret = SOCKET_ERROR; - } - release_sock_fd( s, fd ); - - /* The wineserver may have swallowed the error before us */ - if (!ret && *(int*) optval == 0) - { - int i, events[FD_MAX_EVENTS]; - _get_sock_errors(s, events); - for (i = 0; i < FD_MAX_EVENTS; i++) - { - if(events[i]) - { - TRACE("returning SO_ERROR %d from wine server\n", events[i]); - *(int*) optval = events[i]; - break; - } - } - } - return ret; - } + return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_ERROR, optval, optlen );
case WS_SO_LINGER: { diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 7534e75edb3..9f461376853 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1295,7 +1295,6 @@ todo_wine SetLastError(0xdeadbeef); i = 4321; err = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, &size); -todo_wine ok( !err && !WSAGetLastError(), "got %d with %d (expected 0 with 0)\n", err, WSAGetLastError()); @@ -1306,7 +1305,6 @@ todo_wine SetLastError(0xdeadbeef); size = 1; err = getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &i, &size); -todo_wine ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEFAULT), "got %d with %d (expected SOCKET_ERROR with WSAEFAULT)\n", err, WSAGetLastError());
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- server/protocol.def | 12 ------------ server/sock.c | 39 --------------------------------------- 2 files changed, 51 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def index b5bc049ccf6..343febda6c5 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1423,18 +1423,6 @@ enum server_fd_type @END
-/* Get socket event parameters */ -@REQ(get_socket_event) - obj_handle_t handle; /* handle to the socket */ - int service; /* clear pending? */ - obj_handle_t c_event; /* event to clear */ -@REPLY - unsigned int mask; /* event mask */ - unsigned int pmask; /* pending events */ - VARARG(errors,ints); /* event errors */ -@END - - /* Perform a recv on a socket */ @REQ(recv_socket) int oob; /* are we receiving OOB data? */ diff --git a/server/sock.c b/server/sock.c index f614bf5feaa..e7754dc0da3 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2976,45 +2976,6 @@ struct object *create_socket_device( struct object *root, const struct unicode_s return create_named_object( root, &socket_device_ops, name, attr, sd ); }
-/* get socket event parameters */ -DECL_HANDLER(get_socket_event) -{ - unsigned int errors[FD_MAX_EVENTS] = {0}; - struct sock *sock; - - if (!(sock = (struct sock *)get_handle_obj( current->process, req->handle, - FILE_READ_ATTRIBUTES, &sock_ops ))) return; - if (get_unix_fd( sock->fd ) == -1) return; - reply->mask = afd_poll_flag_to_win32( sock->mask ); - reply->pmask = afd_poll_flag_to_win32( sock->pending_events ); - - errors[FD_READ_BIT] = sock_get_error( sock->errors[AFD_POLL_BIT_READ] ); - errors[FD_WRITE_BIT] = sock_get_error( sock->errors[AFD_POLL_BIT_WRITE] ); - errors[FD_OOB_BIT] = sock_get_error( sock->errors[AFD_POLL_BIT_OOB] ); - errors[FD_ACCEPT_BIT] = sock_get_error( sock->errors[AFD_POLL_BIT_ACCEPT] ); - errors[FD_CONNECT_BIT] = sock_get_error( sock->errors[AFD_POLL_BIT_CONNECT_ERR] ); - if (!(errors[FD_CLOSE_BIT] = sock_get_error( sock->errors[AFD_POLL_BIT_HUP] ))) - errors[FD_CLOSE_BIT] = sock_get_error( sock->errors[AFD_POLL_BIT_RESET] ); - set_reply_data( errors, min( get_reply_max_size(), sizeof(errors) )); - - if (req->service) - { - if (req->c_event) - { - struct event *cevent = get_event_obj( current->process, req->c_event, - EVENT_MODIFY_STATE ); - if (cevent) - { - reset_event( cevent ); - release_object( cevent ); - } - } - sock->pending_events = 0; - sock_reselect( sock ); - } - release_object( &sock->obj ); -} - DECL_HANDLER(recv_socket) { struct sock *sock = (struct sock *)get_handle_obj( current->process, req->async.handle, 0, &sock_ops );
This returns ENOPROTOOPT on Linux, but succeeds on Windows.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index b183b85b0b3..2dd3cf20752 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3548,6 +3548,11 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, case WS_SO_BROADCAST: return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_BROADCAST, optval, optlen );
+ case WS_SO_ERROR: + FIXME( "SO_ERROR, stub!\n" ); + SetLastError( WSAENOPROTOOPT ); + return -1; + /* Some options need some conversion before they can be sent to * setsockopt. The conversions are done here, then they will fall through * to the general case. Special options that are not passed to @@ -3603,7 +3608,6 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, /* The options listed here don't need any special handling. Thanks to * the conversion happening above, options from there will fall through * to this, too.*/ - case WS_SO_ERROR: case WS_SO_KEEPALIVE: case WS_SO_OOBINLINE: /* BSD socket SO_REUSEADDR is not 100% compatible to winsock semantics.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/unix/socket.c | 3 +++ dlls/ws2_32/socket.c | 4 +++- include/wine/afd.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index 959f0e7bc00..e23997bc476 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -1607,6 +1607,9 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc case IOCTL_AFD_WINE_SET_SO_BROADCAST: return do_setsockopt( handle, io, SOL_SOCKET, SO_BROADCAST, in_buffer, in_size );
+ case IOCTL_AFD_WINE_GET_SO_KEEPALIVE: + return do_getsockopt( handle, io, SOL_SOCKET, SO_KEEPALIVE, out_buffer, out_size ); + default: { if ((code >> 16) == FILE_DEVICE_NETWORK) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 2dd3cf20752..4381c4f0408 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2090,7 +2090,6 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
/* Handle common cases. The special cases are below, sorted * alphabetically */ - case WS_SO_KEEPALIVE: case WS_SO_OOBINLINE: case WS_SO_RCVBUF: case WS_SO_REUSEADDR: @@ -2225,6 +2224,9 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, case WS_SO_ERROR: return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_ERROR, optval, optlen );
+ case WS_SO_KEEPALIVE: + return server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_KEEPALIVE, optval, optlen ); + case WS_SO_LINGER: { struct linger lingval; diff --git a/include/wine/afd.h b/include/wine/afd.h index 0ccd248e614..93e1b2c1b1c 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -163,6 +163,7 @@ struct afd_get_events_params #define IOCTL_AFD_WINE_GET_SO_BROADCAST CTL_CODE(FILE_DEVICE_NETWORK, 220, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_SET_SO_BROADCAST CTL_CODE(FILE_DEVICE_NETWORK, 221, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_SO_ERROR CTL_CODE(FILE_DEVICE_NETWORK, 222, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_WINE_GET_SO_KEEPALIVE CTL_CODE(FILE_DEVICE_NETWORK, 223, 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=93012
Your paranoid android.
=== debiant2 (32 bit WoW report) ===
ws2_32: sock.c:5787: Test succeeded inside todo block: expected failure sock.c:5788: Test succeeded inside todo block: got error 64
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/unix/socket.c | 3 +++ dlls/ws2_32/socket.c | 4 +++- include/wine/afd.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index e23997bc476..7b62c5aef68 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -1610,6 +1610,9 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc case IOCTL_AFD_WINE_GET_SO_KEEPALIVE: return do_getsockopt( handle, io, SOL_SOCKET, SO_KEEPALIVE, out_buffer, out_size );
+ case IOCTL_AFD_WINE_SET_SO_KEEPALIVE: + return do_setsockopt( handle, io, SOL_SOCKET, SO_KEEPALIVE, in_buffer, in_size ); + default: { if ((code >> 16) == FILE_DEVICE_NETWORK) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 4381c4f0408..c35972c1d27 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3555,6 +3555,9 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, SetLastError( WSAENOPROTOOPT ); return -1;
+ case WS_SO_KEEPALIVE: + return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_KEEPALIVE, optval, optlen ); + /* Some options need some conversion before they can be sent to * setsockopt. The conversions are done here, then they will fall through * to the general case. Special options that are not passed to @@ -3610,7 +3613,6 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, /* The options listed here don't need any special handling. Thanks to * the conversion happening above, options from there will fall through * to this, too.*/ - case WS_SO_KEEPALIVE: case WS_SO_OOBINLINE: /* BSD socket SO_REUSEADDR is not 100% compatible to winsock semantics. * however, using it the BSD way fixes bug 8513 and seems to be what diff --git a/include/wine/afd.h b/include/wine/afd.h index 93e1b2c1b1c..616ba27b679 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -164,6 +164,7 @@ struct afd_get_events_params #define IOCTL_AFD_WINE_SET_SO_BROADCAST CTL_CODE(FILE_DEVICE_NETWORK, 221, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_SO_ERROR CTL_CODE(FILE_DEVICE_NETWORK, 222, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_SO_KEEPALIVE CTL_CODE(FILE_DEVICE_NETWORK, 223, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_WINE_SET_SO_KEEPALIVE CTL_CODE(FILE_DEVICE_NETWORK, 224, 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=93013
Your paranoid android.
=== debiant2 (32 bit WoW report) ===
ntdll: change.c:241: Test failed: should be ready