From dec38ffb075314629f2f1d3b86c752415181736a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 19 May 2020 17:37:08 +0200 Subject: [PATCH] ntdll: Move the wineserver exec support to the Unix library. Signed-off-by: Alexandre Julliard --- dlls/ntdll/ntdll_misc.h | 1 - dlls/ntdll/server.c | 163 +-------------------------------------- dlls/ntdll/thread.c | 2 +- dlls/ntdll/unix/loader.c | 81 +++++++++++++++++++ dlls/ntdll/unixlib.h | 3 +- 5 files changed, 87 insertions(+), 163 deletions(-) diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index b7318fdd311..4321347e723 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -99,7 +99,6 @@ extern void heap_set_debug_flags( HANDLE handle ) DECLSPEC_HIDDEN; extern void init_unix_codepage(void) DECLSPEC_HIDDEN; extern void init_locale( HMODULE module ) DECLSPEC_HIDDEN; extern void init_user_process_params( SIZE_T data_size ) DECLSPEC_HIDDEN; -extern void init_paths(void) DECLSPEC_HIDDEN; extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN; extern NTSTATUS restart_process( RTL_USER_PROCESS_PARAMETERS *params, NTSTATUS status ) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index 99e7b2a6476..78cac72e447 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -127,8 +127,6 @@ const char *build_dir = NULL; const char *data_dir = NULL; const char *config_dir = NULL; static const char *server_dir; -static const char *bin_dir; -static const char *argv0; unsigned int server_cpus = 0; BOOL is_wow64 = FALSE; @@ -191,47 +189,6 @@ static void fatal_perror( const char *err, ... ) exit(1); } -/* canonicalize path and return its directory name */ -static char *realpath_dirname( const char *name ) -{ - char *p, *fullpath = realpath( name, NULL ); - - if (fullpath) - { - p = strrchr( fullpath, '/' ); - if (p == fullpath) p++; - if (p) *p = 0; - } - return fullpath; -} - -/* if string ends with tail, remove it */ -static char *remove_tail( const char *str, const char *tail ) -{ - size_t len = strlen( str ); - size_t tail_len = strlen( tail ); - char *ret; - - if (len < tail_len) return NULL; - if (strcmp( str + len - tail_len, tail )) return NULL; - ret = malloc( len - tail_len + 1 ); - memcpy( ret, str, len - tail_len ); - ret[len - tail_len] = 0; - return ret; -} - -/* build a path from the specified dir and name */ -static char *build_path( const char *dir, const char *name ) -{ - size_t len = strlen( dir ); - char *ret = malloc( len + strlen( name ) + 2 ); - - memcpy( ret, dir, len ); - if (len && ret[len - 1] != '/') ret[len++] = '/'; - strcpy( ret + len, name ); - return ret; -} - /*********************************************************************** * server_protocol_error */ @@ -1223,83 +1180,6 @@ int server_pipe( int fd[2] ) } -/*********************************************************************** - * exec_wineserver - * - * Exec a new wine server. - */ -static void exec_wineserver( char **argv ) -{ - char *path; - - if (build_dir) - { - if (!is_win64) /* look for 64-bit server */ - { - char *loader = realpath_dirname( build_path( build_dir, "loader/wine64" )); - if (loader) - { - argv[0] = build_path( loader, "../server/wineserver" ); - execv( argv[0], argv ); - } - } - argv[0] = build_path( build_dir, "server/wineserver" ); - execv( argv[0], argv ); - return; - } - - argv[0] = build_path( bin_dir, "wineserver" ); - execv( argv[0], argv ); - - argv[0] = getenv( "WINESERVER" ); - if (argv[0]) execv( argv[0], argv ); - - if ((path = getenv( "PATH" ))) - { - for (path = strtok( strdup( path ), ":" ); path; path = strtok( NULL, ":" )) - { - argv[0] = build_path( path, "wineserver" ); - execvp( argv[0], argv ); - } - } - - argv[0] = build_path( BINDIR, "wineserver" ); - execv( argv[0], argv ); -} - - -/*********************************************************************** - * start_server - * - * Start a new wine server. - */ -static void start_server(void) -{ - static BOOL started; /* we only try once */ - char *argv[3]; - static char debug[] = "-d"; - - if (!started) - { - int status; - int pid = fork(); - if (pid == -1) fatal_perror( "fork" ); - if (!pid) - { - argv[1] = TRACE_ON(server) ? debug : NULL; - argv[2] = NULL; - exec_wineserver( argv ); - fatal_error( "could not exec wineserver\n" ); - } - waitpid( pid, &status, 0 ); - status = WIFEXITED(status) ? WEXITSTATUS(status) : 1; - if (status == 2) return; /* server lock held by someone else, will retry later */ - if (status) exit(status); /* server failed */ - started = TRUE; - } -} - - /*********************************************************************** * init_server_dir */ @@ -1332,43 +1212,6 @@ static const char *init_server_dir( dev_t dev, ino_t ino ) } -/*********************************************************************** - * init_paths - */ -void init_paths(void) -{ - const char *dll_dir = NULL; - -#ifdef HAVE_DLADDR - Dl_info info; - - if (dladdr( init_paths, &info ) && info.dli_fname[0] == '/') - dll_dir = realpath_dirname( info.dli_fname ); -#endif - - argv0 = strdup( __wine_main_argv[0] ); - -#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) - bin_dir = realpath_dirname( "/proc/self/exe" ); -#elif defined (__FreeBSD__) || defined(__DragonFly__) - bin_dir = realpath_dirname( "/proc/curproc/file" ); -#else - bin_dir = realpath_dirname( argv0 ); -#endif - - if (dll_dir) build_dir = remove_tail( dll_dir, "/dlls/ntdll" ); - else if (bin_dir) build_dir = remove_tail( bin_dir, "/loader" ); - - if (!build_dir) - { - if (!bin_dir) bin_dir = dll_dir ? build_path( dll_dir, DLL_TO_BINDIR ) : BINDIR; - else if (!dll_dir) dll_dir = build_path( bin_dir, BIN_TO_DLLDIR ); - } - - unix_funcs->get_paths( &build_dir, &data_dir, &config_dir ); -} - - /*********************************************************************** * setup_config_dir * @@ -1467,7 +1310,7 @@ static int server_connect(void) if (chdir( server_dir ) == -1) { if (errno != ENOENT) fatal_perror( "chdir to %s", server_dir ); - start_server(); + unix_funcs->start_server( TRACE_ON(server) ); if (chdir( server_dir ) == -1) fatal_perror( "chdir to %s", server_dir ); } @@ -1482,13 +1325,13 @@ static int server_connect(void) if (retry) { usleep( 100000 * retry * retry ); - start_server(); + unix_funcs->start_server( TRACE_ON(server) ); if (lstat( SOCKETNAME, &st ) == -1) continue; /* still no socket, wait a bit more */ } else if (lstat( SOCKETNAME, &st ) == -1) /* check for an already existing socket */ { if (errno != ENOENT) fatal_perror( "lstat %s/%s", server_dir, SOCKETNAME ); - start_server(); + unix_funcs->start_server( TRACE_ON(server) ); if (lstat( SOCKETNAME, &st ) == -1) continue; /* still no socket, wait a bit more */ } diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 2de2804f8c9..a5e1fadac9b 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -381,7 +381,7 @@ TEB *thread_init(void) thread_data->wait_fd[1] = -1; unix_funcs->dbg_init(); - init_paths(); + unix_funcs->get_paths( &build_dir, &data_dir, &config_dir ); set_process_name( __wine_main_argc, __wine_main_argv ); /* initialize time values in user_shared_data */ diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 9028b2de81e..4975a5689ec 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -42,6 +42,9 @@ #ifdef HAVE_SYS_UTSNAME_H #include #endif +#ifdef HAVE_SYS_WAIT_H +#include +#endif #ifdef __APPLE__ # include # define LoadResource MacLoadResource @@ -484,6 +487,83 @@ static NTSTATUS CDECL exec_wineloader( char **argv, int socketfd, int is_child_6 } +/*********************************************************************** + * exec_wineserver + * + * Exec a new wine server. + */ +static void exec_wineserver( char **argv ) +{ + char *path; + + if (build_dir) + { + if (!is_win64) /* look for 64-bit server */ + { + char *loader = realpath_dirname( build_path( build_dir, "loader/wine64" )); + if (loader) + { + argv[0] = build_path( loader, "../server/wineserver" ); + execv( argv[0], argv ); + } + } + argv[0] = build_path( build_dir, "server/wineserver" ); + execv( argv[0], argv ); + return; + } + + argv[0] = build_path( bin_dir, "wineserver" ); + execv( argv[0], argv ); + + argv[0] = getenv( "WINESERVER" ); + if (argv[0]) execv( argv[0], argv ); + + if ((path = getenv( "PATH" ))) + { + for (path = strtok( strdup( path ), ":" ); path; path = strtok( NULL, ":" )) + { + argv[0] = build_path( path, "wineserver" ); + execvp( argv[0], argv ); + } + } + + argv[0] = build_path( BINDIR, "wineserver" ); + execv( argv[0], argv ); +} + + +/*********************************************************************** + * start_server + * + * Start a new wine server. + */ +static void CDECL start_server( BOOL debug ) +{ + static BOOL started; /* we only try once */ + char *argv[3]; + static char debug_flag[] = "-d"; + + if (!started) + { + int status; + int pid = fork(); + if (pid == -1) fatal_error( "fork: %s", strerror(errno) ); + if (!pid) + { + argv[1] = debug ? debug_flag : NULL; + argv[2] = NULL; + exec_wineserver( argv ); + fatal_error( "could not exec wineserver\n" ); + } + waitpid( pid, &status, 0 ); + status = WIFEXITED(status) ? WEXITSTATUS(status) : 1; + if (status == 2) return; /* server lock held by someone else, will retry later */ + if (status) exit(status); /* server failed */ + started = TRUE; + } +} + + /************************************************************************* * map_so_dll * @@ -760,6 +840,7 @@ static struct unix_funcs unix_funcs = get_build_id, get_host_version, exec_wineloader, + start_server, map_so_dll, mmap_add_reserved_area, mmap_remove_reserved_area, diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h index e7767fd5aac..69a0bf81891 100644 --- a/dlls/ntdll/unixlib.h +++ b/dlls/ntdll/unixlib.h @@ -24,7 +24,7 @@ #include "wine/debug.h" /* increment this when you change the function table */ -#define NTDLL_UNIXLIB_VERSION 5 +#define NTDLL_UNIXLIB_VERSION 6 struct unix_funcs { @@ -39,6 +39,7 @@ struct unix_funcs /* loader functions */ NTSTATUS (CDECL *exec_wineloader)( char **argv, int socketfd, int is_child_64bit, ULONGLONG res_start, ULONGLONG res_end ); + void (CDECL *start_server)( BOOL debug ); /* virtual memory functions */ NTSTATUS (CDECL *map_so_dll)( const IMAGE_NT_HEADERS *nt_descr, HMODULE module );