[PATCH 2/3] server: Don't reset socket error in poll_socket.
Piotr Caban
wine at gitlab.winehq.org
Fri Jun 10 11:01:02 CDT 2022
From: Piotr Caban <piotr at codeweavers.com>
Otherwise socket error may be cleared in poll_socket causing ioctl SO_ERROR calls to return no error.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51433
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
---
server/sock.c | 34 ++++++++++++++++++++++++++--------
1 file changed, 26 insertions(+), 8 deletions(-)
diff --git a/server/sock.c b/server/sock.c
index 8a0f3198c4e..c4bbd388097 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -631,13 +631,28 @@ static void sock_wake_up( struct sock *sock )
}
}
-static inline int sock_error( struct fd *fd )
+static inline int sock_error( struct sock *sock, int *error )
{
- unsigned int optval = 0;
- socklen_t optlen = sizeof(optval);
+ socklen_t len = sizeof(*error);
- getsockopt( get_unix_fd(fd), SOL_SOCKET, SO_ERROR, (void *) &optval, &optlen);
- return optval;
+ if (getsockopt( get_unix_fd(sock->fd), SOL_SOCKET, SO_ERROR, (void *)error, &len) < 0)
+ return -1;
+
+ if (sock->state == SOCK_CONNECTING)
+ {
+ if (*error)
+ sock->errors[AFD_POLL_BIT_CONNECT_ERR] = *error;
+ else
+ *error = sock->errors[AFD_POLL_BIT_CONNECT_ERR];
+ }
+ else if (sock->state == SOCK_LISTENING)
+ {
+ if (*error)
+ sock->errors[AFD_POLL_BIT_ACCEPT] = *error;
+ else
+ *error = sock->errors[AFD_POLL_BIT_CONNECT_ERR];
+ }
+ return 0;
}
static void free_accept_req( void *private )
@@ -1120,9 +1135,9 @@ static void sock_poll_event( struct fd *fd, int event )
case SOCK_CONNECTING:
if (event & (POLLERR|POLLHUP))
{
+ sock_error( sock, &error );
sock->state = SOCK_UNCONNECTED;
event &= ~POLLOUT;
- error = sock_error( fd );
}
else if (event & POLLOUT)
{
@@ -1133,7 +1148,7 @@ static void sock_poll_event( struct fd *fd, int event )
case SOCK_LISTENING:
if (event & (POLLERR|POLLHUP))
- error = sock_error( fd );
+ sock_error( sock, &error );
break;
case SOCK_CONNECTED:
@@ -3123,9 +3138,12 @@ static void poll_socket( struct sock *poll_sock, struct async *async, int exclus
if (flags)
{
+ int error = 0;
+
signaled = TRUE;
req->sockets[i].flags = flags;
- req->sockets[i].status = sock_get_ntstatus( sock_error( sock->fd ) );
+ sock_error( sock, &error );
+ req->sockets[i].status = sock_get_ntstatus( error );
}
/* FIXME: do other error conditions deserve a similar treatment? */
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/225
More information about the wine-devel
mailing list