From 70073ff2d04e96a262e0e8bc59406e3572af4781 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 20 Nov 2018 15:53:30 +0100 Subject: [PATCH] server: Return a WSA error code in accept_socket. Signed-off-by: Alexandre Julliard --- dlls/ws2_32/socket.c | 29 ++++++++++++++--------------- server/sock.c | 21 +++++---------------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 2207586dd82..640726d01eb 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2521,7 +2521,7 @@ static NTSTATUS WS2_async_accept( void *user, IO_STATUS_BLOCK *iosb, NTSTATUS st } SERVER_END_REQ; - if (status == STATUS_CANT_WAIT) + if (NtStatusToWSAError( status ) == WSAEWOULDBLOCK) return STATUS_PENDING; if (status == STATUS_INVALID_HANDLE) @@ -2760,9 +2760,9 @@ static int WS2_register_async_shutdown( SOCKET s, int type ) */ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr, int *addrlen32) { - NTSTATUS status; DWORD err; SOCKET as; + int fd; BOOL is_blocking; TRACE("socket %04lx\n", s ); @@ -2770,18 +2770,19 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr, int *addrlen32) if (err) goto error; - do { + for (;;) + { /* try accepting first (if there is a deferred connection) */ SERVER_START_REQ( accept_socket ) { req->lhandle = wine_server_obj_handle( SOCKET2HANDLE(s) ); req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE; req->attributes = OBJ_INHERIT; - status = wine_server_call( req ); + err = NtStatusToWSAError( wine_server_call( req )); as = HANDLE2SOCKET( wine_server_ptr_handle( reply->handle )); } SERVER_END_REQ; - if (!status) + if (!err) { if (addr && addrlen32 && WS_getpeername(as, addr, addrlen32)) { @@ -2791,16 +2792,14 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr, int *addrlen32) TRACE("\taccepted %04lx\n", as); return as; } - if (is_blocking && status == STATUS_CANT_WAIT) - { - int fd = get_sock_fd( s, FILE_READ_DATA, NULL ); - /* block here */ - do_block(fd, POLLIN, -1); - _sync_sock_state(s); /* let wineserver notice connection */ - release_sock_fd( s, fd ); - } - } while (is_blocking && status == STATUS_CANT_WAIT); - err = NtStatusToWSAError( status ); + if (!is_blocking) break; + if (err != WSAEWOULDBLOCK) break; + fd = get_sock_fd( s, FILE_READ_DATA, NULL ); + /* block here */ + do_block(fd, POLLIN, -1); + _sync_sock_state(s); /* let wineserver notice connection */ + release_sock_fd( s, fd ); + } error: WARN(" -> ERROR %d\n", err); diff --git a/server/sock.c b/server/sock.c index a9bd55a695d..284ab9ff78a 100644 --- a/server/sock.c +++ b/server/sock.c @@ -135,7 +135,6 @@ static void sock_reselect_async( struct fd *fd, struct async_queue *queue ); static int sock_get_ntstatus( int err ); static unsigned int sock_get_error( int err ); -static void sock_set_error(void); static const struct object_ops sock_ops = { @@ -699,17 +698,13 @@ static int accept_new_fd( struct sock *sock ) * or that accept() is allowed on it. In those cases we will get -1/errno * return. */ - int acceptfd; struct sockaddr saddr; socklen_t slen = sizeof(saddr); - acceptfd = accept( get_unix_fd(sock->fd), &saddr, &slen); - if (acceptfd == -1) - { - sock_set_error(); - return acceptfd; - } - - fcntl(acceptfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */ + int acceptfd = accept( get_unix_fd(sock->fd), &saddr, &slen ); + if (acceptfd != -1) + fcntl( acceptfd, F_SETFL, O_NONBLOCK ); + else + set_win32_error( sock_get_error( errno )); return acceptfd; } @@ -936,12 +931,6 @@ static int sock_get_ntstatus( int err ) } } -/* set the last error depending on errno */ -static void sock_set_error(void) -{ - set_error( sock_get_ntstatus( errno ) ); -} - #ifdef HAVE_LINUX_RTNETLINK_H /* only keep one ifchange object around, all sockets waiting for wakeups will look to it */