[PATCH v3 2/3] server: Don't reset socket error in poll_socket.
Piotr Caban
wine at gitlab.winehq.org
Sat Jun 11 05:59:53 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 | 30 ++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/server/sock.c b/server/sock.c
index 8a0f3198c4e..439801a8cfa 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -631,13 +631,27 @@ static void sock_wake_up( struct sock *sock )
}
}
-static inline int sock_error( struct fd *fd )
+static inline int sock_error( struct sock *sock )
{
- unsigned int optval = 0;
- socklen_t optlen = sizeof(optval);
+ int error = 0;
+ socklen_t len = sizeof(error);
- getsockopt( get_unix_fd(fd), SOL_SOCKET, SO_ERROR, (void *) &optval, &optlen);
- return optval;
+ getsockopt( get_unix_fd(sock->fd), SOL_SOCKET, SO_ERROR, (void *)&error, &len);
+ 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_ACCEPT];
+ }
+ return error;
}
static void free_accept_req( void *private )
@@ -1120,9 +1134,9 @@ static void sock_poll_event( struct fd *fd, int event )
case SOCK_CONNECTING:
if (event & (POLLERR|POLLHUP))
{
+ error = sock_error( sock );
sock->state = SOCK_UNCONNECTED;
event &= ~POLLOUT;
- error = sock_error( fd );
}
else if (event & POLLOUT)
{
@@ -1133,7 +1147,7 @@ static void sock_poll_event( struct fd *fd, int event )
case SOCK_LISTENING:
if (event & (POLLERR|POLLHUP))
- error = sock_error( fd );
+ error = sock_error( sock );
break;
case SOCK_CONNECTED:
@@ -3125,7 +3139,7 @@ static void poll_socket( struct sock *poll_sock, struct async *async, int exclus
{
signaled = TRUE;
req->sockets[i].flags = flags;
- req->sockets[i].status = sock_get_ntstatus( sock_error( sock->fd ) );
+ req->sockets[i].status = sock_get_ntstatus( sock_error( sock ) );
}
/* 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