From 01150d7f8d27ad5efdb824da938c4a9fa562a036 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 29 May 2020 15:53:42 +0200 Subject: [PATCH] ntdll: Move server call functions to the Unix library. Signed-off-by: Alexandre Julliard --- dlls/ntdll/ntdll_misc.h | 1 - dlls/ntdll/server.c | 102 +----------------------------- dlls/ntdll/unix/loader.c | 2 + dlls/ntdll/unix/server.c | 109 +++++++++++++++++++++++++++++++++ dlls/ntdll/unix/unix_private.h | 1 + dlls/ntdll/unixlib.h | 4 +- dlls/ntdll/virtual.c | 2 +- 7 files changed, 118 insertions(+), 103 deletions(-) diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 6c7acd1d30d..824e64f5122 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -119,7 +119,6 @@ extern void server_init_process_done(void) DECLSPEC_HIDDEN; extern void DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN; extern void DECLSPEC_NORETURN exit_thread( int status ) DECLSPEC_HIDDEN; extern sigset_t server_block_set DECLSPEC_HIDDEN; -extern unsigned int server_call_unlocked( void *req_ptr ) DECLSPEC_HIDDEN; extern void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) DECLSPEC_HIDDEN; extern void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) DECLSPEC_HIDDEN; extern unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags, diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index 9fb0cc9e35c..ed4e3f25531 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -142,98 +142,6 @@ static DECLSPEC_NORETURN void server_protocol_perror( const char *err ) } -/*********************************************************************** - * send_request - * - * Send a request to the server. - */ -static unsigned int send_request( const struct __server_request_info *req ) -{ - unsigned int i; - int ret; - - if (!req->u.req.request_header.request_size) - { - if ((ret = write( ntdll_get_thread_data()->request_fd, &req->u.req, - sizeof(req->u.req) )) == sizeof(req->u.req)) return STATUS_SUCCESS; - - } - else - { - struct iovec vec[__SERVER_MAX_DATA+1]; - - vec[0].iov_base = (void *)&req->u.req; - vec[0].iov_len = sizeof(req->u.req); - for (i = 0; i < req->data_count; i++) - { - vec[i+1].iov_base = (void *)req->data[i].ptr; - vec[i+1].iov_len = req->data[i].size; - } - if ((ret = writev( ntdll_get_thread_data()->request_fd, vec, i+1 )) == - req->u.req.request_header.request_size + sizeof(req->u.req)) return STATUS_SUCCESS; - } - - if (ret >= 0) server_protocol_error( "partial write %d\n", ret ); - if (errno == EPIPE) abort_thread(0); - if (errno == EFAULT) return STATUS_ACCESS_VIOLATION; - server_protocol_perror( "write" ); -} - - -/*********************************************************************** - * read_reply_data - * - * Read data from the reply buffer; helper for wait_reply. - */ -static void read_reply_data( void *buffer, size_t size ) -{ - int ret; - - for (;;) - { - if ((ret = read( ntdll_get_thread_data()->reply_fd, buffer, size )) > 0) - { - if (!(size -= ret)) return; - buffer = (char *)buffer + ret; - continue; - } - if (!ret) break; - if (errno == EINTR) continue; - if (errno == EPIPE) break; - server_protocol_perror("read"); - } - /* the server closed the connection; time to die... */ - abort_thread(0); -} - - -/*********************************************************************** - * wait_reply - * - * Wait for a reply from the server. - */ -static inline unsigned int wait_reply( struct __server_request_info *req ) -{ - read_reply_data( &req->u.reply, sizeof(req->u.reply) ); - if (req->u.reply.reply_header.reply_size) - read_reply_data( req->reply_data, req->u.reply.reply_header.reply_size ); - return req->u.reply.reply_header.error; -} - - -/*********************************************************************** - * server_call_unlocked - */ -unsigned int server_call_unlocked( void *req_ptr ) -{ - struct __server_request_info * const req = req_ptr; - unsigned int ret; - - if ((ret = send_request( req ))) return ret; - return wait_reply( req ); -} - - /*********************************************************************** * wine_server_call (NTDLL.@) * @@ -258,13 +166,7 @@ unsigned int server_call_unlocked( void *req_ptr ) */ unsigned int CDECL wine_server_call( void *req_ptr ) { - sigset_t old_set; - unsigned int ret; - - pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set ); - ret = server_call_unlocked( req_ptr ); - pthread_sigmask( SIG_SETMASK, &old_set, NULL ); - return ret; + return unix_funcs->server_call( req_ptr ); } @@ -582,7 +484,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT suspend_context = FALSE; /* server owns the context now */ } if (context) wine_server_set_reply( req, &server_context, sizeof(server_context) ); - ret = server_call_unlocked( req ); + ret = unix_funcs->server_call_unlocked( req ); apc_handle = reply->apc_handle; call = reply->call; if (wine_server_reply_size( reply )) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 38fd930d33d..4a3f101d301 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -996,6 +996,8 @@ static struct unix_funcs unix_funcs = mmap_remove_reserved_area, mmap_is_in_reserved_area, mmap_enum_reserved_areas, + server_call_unlocked, + wine_server_call, server_send_fd, server_remove_fd_from_cache, server_get_unix_fd, diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 0d3cd28dc9b..8dc3f33bc80 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -205,6 +205,115 @@ static DECLSPEC_NORETURN void server_protocol_perror( const char *err ) } +/*********************************************************************** + * send_request + * + * Send a request to the server. + */ +static unsigned int send_request( const struct __server_request_info *req ) +{ + unsigned int i; + int ret; + + if (!req->u.req.request_header.request_size) + { + if ((ret = write( ntdll_get_thread_data()->request_fd, &req->u.req, + sizeof(req->u.req) )) == sizeof(req->u.req)) return STATUS_SUCCESS; + + } + else + { + struct iovec vec[__SERVER_MAX_DATA+1]; + + vec[0].iov_base = (void *)&req->u.req; + vec[0].iov_len = sizeof(req->u.req); + for (i = 0; i < req->data_count; i++) + { + vec[i+1].iov_base = (void *)req->data[i].ptr; + vec[i+1].iov_len = req->data[i].size; + } + if ((ret = writev( ntdll_get_thread_data()->request_fd, vec, i+1 )) == + req->u.req.request_header.request_size + sizeof(req->u.req)) return STATUS_SUCCESS; + } + + if (ret >= 0) server_protocol_error( "partial write %d\n", ret ); + if (errno == EPIPE) NtTerminateThread( GetCurrentThread(), 0 ); + if (errno == EFAULT) return STATUS_ACCESS_VIOLATION; + server_protocol_perror( "write" ); +} + + +/*********************************************************************** + * read_reply_data + * + * Read data from the reply buffer; helper for wait_reply. + */ +static void read_reply_data( void *buffer, size_t size ) +{ + int ret; + + for (;;) + { + if ((ret = read( ntdll_get_thread_data()->reply_fd, buffer, size )) > 0) + { + if (!(size -= ret)) return; + buffer = (char *)buffer + ret; + continue; + } + if (!ret) break; + if (errno == EINTR) continue; + if (errno == EPIPE) break; + server_protocol_perror("read"); + } + /* the server closed the connection; time to die... */ + for (;;) NtTerminateThread( GetCurrentThread(), 0 ); +} + + +/*********************************************************************** + * wait_reply + * + * Wait for a reply from the server. + */ +static inline unsigned int wait_reply( struct __server_request_info *req ) +{ + read_reply_data( &req->u.reply, sizeof(req->u.reply) ); + if (req->u.reply.reply_header.reply_size) + read_reply_data( req->reply_data, req->u.reply.reply_header.reply_size ); + return req->u.reply.reply_header.error; +} + + +/*********************************************************************** + * server_call_unlocked + */ +unsigned int CDECL server_call_unlocked( void *req_ptr ) +{ + struct __server_request_info * const req = req_ptr; + unsigned int ret; + + if ((ret = send_request( req ))) return ret; + return wait_reply( req ); +} + + +/*********************************************************************** + * wine_server_call + * + * Perform a server call. + */ +unsigned int CDECL wine_server_call( void *req_ptr ) +{ + sigset_t old_set; + unsigned int ret; + + pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set ); + ret = server_call_unlocked( req_ptr ); + pthread_sigmask( SIG_SETMASK, &old_set, NULL ); + return ret; +} + + /*********************************************************************** * server_enter_uninterrupted_section */ diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 9d2b3892cc8..2bf39f85371 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -60,6 +60,7 @@ extern void virtual_init(void) DECLSPEC_HIDDEN; extern void CDECL dbg_init(void) DECLSPEC_HIDDEN; +extern unsigned int CDECL server_call_unlocked( void *req_ptr ) DECLSPEC_HIDDEN; extern void CDECL server_send_fd( int fd ) DECLSPEC_HIDDEN; extern int CDECL server_remove_fd_from_cache( HANDLE handle ) DECLSPEC_HIDDEN; extern int CDECL server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd, diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h index bbdb36e579d..142e8956e7e 100644 --- a/dlls/ntdll/unixlib.h +++ b/dlls/ntdll/unixlib.h @@ -25,7 +25,7 @@ #include "wine/debug.h" /* increment this when you change the function table */ -#define NTDLL_UNIXLIB_VERSION 9 +#define NTDLL_UNIXLIB_VERSION 10 struct unix_funcs { @@ -51,6 +51,8 @@ struct unix_funcs void *arg, int top_down ); /* server functions */ + unsigned int (CDECL *server_call_unlocked)( void *req_ptr ); + unsigned int (CDECL *server_call)( void *req_ptr ); void (CDECL *server_send_fd)( int fd ); int (CDECL *server_remove_fd_from_cache)( HANDLE handle ); int (CDECL *server_get_unix_fd)( HANDLE handle, unsigned int wanted_access, int *unix_fd, diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 5c83a117868..0ba46c35ac8 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -2390,7 +2390,7 @@ unsigned int virtual_locked_server_call( void *req_ptr ) server_enter_uninterrupted_section( &csVirtual, &sigset ); if (!(ret = check_write_access( addr, size, &has_write_watch ))) { - ret = server_call_unlocked( req ); + ret = unix_funcs->server_call_unlocked( req ); if (has_write_watch) update_write_watches( addr, size, wine_server_reply_size( req )); } server_leave_uninterrupted_section( &csVirtual, &sigset );