From 48182726e93be7a573c989c822b52eb56d5fbad9 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 6 Dec 2023 11:38:45 +0100 Subject: [PATCH] ntdll: Use posix_spawn() to start the server. Based on a patch by Brendan Shanks. --- dlls/ntdll/unix/loader.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 7b7005d282d..ee71584b953 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -69,7 +70,6 @@ # include # include # include -# include # ifndef _POSIX_SPAWN_DISABLE_ASLR # define _POSIX_SPAWN_DISABLE_ASLR 0x0100 # endif @@ -77,6 +77,7 @@ #ifdef __ANDROID__ # include #endif +extern char **environ; #include "ntstatus.h" #define WIN32_NO_STATUS @@ -309,11 +310,14 @@ static char *build_path( const char *dir, const char *name ) /* build a path to a binary and exec it */ -static void build_path_and_exec( const char *dir, const char *name, char **argv ) +static int build_path_and_exec( pid_t *pid, const char *dir, const char *name, char **argv ) { + int ret; + argv[0] = build_path( dir, name ); - execv( argv[0], argv ); + ret = posix_spawn( pid, argv[0], NULL, NULL, argv, environ ); free( argv[0] ); + return ret; } @@ -567,7 +571,7 @@ NTSTATUS exec_wineloader( char **argv, int socketfd, const pe_image_info_t *pe_i * * Exec a new wine server. */ -static void exec_wineserver( char **argv ) +static int exec_wineserver( pid_t *pid, char **argv ) { char *path; @@ -576,22 +580,20 @@ static void exec_wineserver( char **argv ) if (!is_win64) /* look for 64-bit server */ { char *loader = realpath_dirname( build_path( build_dir, "loader/wine64" )); - if (loader) build_path_and_exec( loader, "../server/wineserver", argv ); + if (loader && !build_path_and_exec( pid, loader, "../server/wineserver", argv )) return 0; } - build_path_and_exec( build_dir, "server/wineserver", argv ); - return; + return build_path_and_exec( pid, build_dir, "server/wineserver", argv ); } - build_path_and_exec( bin_dir, "wineserver", argv ); - - if ((path = getenv( "WINESERVER" ))) build_path_and_exec( "", path, argv ); + if (!build_path_and_exec( pid, bin_dir, "wineserver", argv )) return 0; + if ((path = getenv( "WINESERVER" )) && !build_path_and_exec( pid, "", path, argv )) return 0; if ((path = getenv( "PATH" ))) { for (path = strtok( strdup( path ), ":" ); path; path = strtok( NULL, ":" )) - build_path_and_exec( path, "wineserver", argv ); + if (!build_path_and_exec( pid, path, "wineserver", argv )) return 0; } - build_path_and_exec( BINDIR, "wineserver", argv ); + return build_path_and_exec( pid, BINDIR, "wineserver", argv ); } @@ -609,15 +611,11 @@ void start_server( BOOL debug ) 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" ); - } + pid_t pid; + + argv[1] = debug ? debug_flag : NULL; + argv[2] = NULL; + if (exec_wineserver( &pid, 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 */