diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index c81ba03947e..5a7678daf5d 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -1481,14 +1481,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW if (winedebug) putenv( winedebug ); if (unixdir) chdir(unixdir); - if (argv) - { - /* first, try for a WINELOADER environment variable */ - const char *loader = getenv("WINELOADER"); - if (loader) wine_exec_wine_binary( loader, argv, NULL, TRUE ); - /* now use the standard search strategy */ - wine_exec_wine_binary( NULL, argv, NULL, TRUE ); - } + if (argv) wine_exec_wine_binary( NULL, argv, getenv("WINELOADER") ); + err = errno; write( execfd[1], &err, sizeof(err) ); _exit(1); diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index 88c00156fa6..dd9baeb7d23 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -589,7 +589,6 @@ void wine_server_release_fd( obj_handle_t handle, int unix_fd ) static void start_server( const char *oldcwd ) { static int started; /* we only try once */ - char *path, *p; char *argv[3]; if (!started) @@ -602,22 +601,7 @@ static void start_server( const char *oldcwd ) argv[0] = "wineserver"; argv[1] = TRACE_ON(server) ? "-d" : NULL; argv[2] = NULL; - /* if server is explicitly specified, use this */ - if ((p = getenv("WINESERVER"))) - { - if (p[0] != '/' && oldcwd[0] == '/') /* make it an absolute path */ - { - if (!(path = malloc( strlen(oldcwd) + strlen(p) + 1 ))) - fatal_error( "out of memory\n" ); - sprintf( path, "%s/%s", oldcwd, p ); - p = path; - } - wine_exec_wine_binary( p, argv, NULL, FALSE ); - fatal_perror( "could not exec the server '%s'\n" - " specified in the WINESERVER environment variable", p ); - } - /* now use the standard search strategy */ - wine_exec_wine_binary( argv[0], argv, NULL, FALSE ); + wine_exec_wine_binary( argv[0], argv, getenv("WINESERVER") ); fatal_error( "could not exec wineserver\n" ); } waitpid( pid, &status, 0 ); @@ -809,7 +793,7 @@ static void create_config_dir(void) argv[3] = "--prefix"; argv[4] = tmp_dir; argv[5] = NULL; - wine_exec_wine_binary( argv[0], (char **)argv, NULL, FALSE ); + wine_exec_wine_binary( argv[0], (char **)argv, NULL ); rmdir( tmp_dir ); fatal_perror( "could not exec wineprefixcreate" ); } diff --git a/include/wine/library.h b/include/wine/library.h index aa689c022d2..e92262c3f0b 100644 --- a/include/wine/library.h +++ b/include/wine/library.h @@ -33,7 +33,7 @@ extern const char *wine_get_config_dir(void); extern const char *wine_get_server_dir(void); extern const char *wine_get_user_name(void); extern void wine_init_argv0_path( const char *argv0 ); -extern void wine_exec_wine_binary( const char *name, char **argv, char **envp, int use_preloader ); +extern void wine_exec_wine_binary( const char *name, char **argv, const char *env_var ); /* dll loading */ diff --git a/libs/wine/config.c b/libs/wine/config.c index e2bdc5abc6b..77dbb5d90fb 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c @@ -375,7 +375,7 @@ const char *wine_get_user_name(void) } /* exec a binary using the preloader if requested; helper for wine_exec_wine_binary */ -static void preloader_exec( char **argv, char **envp, int use_preloader ) +static void preloader_exec( char **argv, int use_preloader ) { #ifdef linux if (use_preloader) @@ -396,36 +396,40 @@ static void preloader_exec( char **argv, char **envp, int use_preloader ) new_argv = xmalloc( (last_arg - argv + 2) * sizeof(*argv) ); memcpy( new_argv + 1, argv, (last_arg - argv + 1) * sizeof(*argv) ); new_argv[0] = full_name; - if (envp) execve( full_name, new_argv, envp ); - else execv( full_name, new_argv ); + execv( full_name, new_argv ); free( new_argv ); free( full_name ); return; } #endif - if (envp) execve( argv[0], argv, envp ); - else execv( argv[0], argv ); + execv( argv[0], argv ); } /* exec a wine internal binary (either the wine loader or the wine server) */ -void wine_exec_wine_binary( const char *name, char **argv, char **envp, int use_preloader ) +void wine_exec_wine_binary( const char *name, char **argv, const char *env_var ) { static const char bindir[] = BINDIR; const char *path, *pos, *ptr; + int use_preloader = 0; - if (name && strchr( name, '/' )) + if (!name) /* no name means default loader */ { - argv[0] = (char *)name; - preloader_exec( argv, envp, use_preloader ); - return; + name = argv0_name; + use_preloader = 1; } - else if (!name) name = argv0_name; /* first, bin directory from the current libdir or argv0 */ argv[0] = get_path_from_libdir( bindir, argv0_path, name ); - preloader_exec( argv, envp, use_preloader ); + preloader_exec( argv, use_preloader ); free( argv[0] ); + /* then specified environment variable */ + if (env_var) + { + argv[0] = (char *)env_var; + preloader_exec( argv, use_preloader ); + } + /* now search in the Unix path */ if ((path = getenv( "PATH" ))) { @@ -439,7 +443,7 @@ void wine_exec_wine_binary( const char *name, char **argv, char **envp, int use_ memcpy( argv[0], pos, ptr - pos ); strcpy( argv[0] + (ptr - pos), "/" ); strcat( argv[0] + (ptr - pos), name ); - preloader_exec( argv, envp, use_preloader ); + preloader_exec( argv, use_preloader ); pos = ptr; } free( argv[0] ); @@ -450,5 +454,5 @@ void wine_exec_wine_binary( const char *name, char **argv, char **envp, int use_ strcpy( argv[0], bindir ); strcat( argv[0], "/" ); strcat( argv[0], name ); - preloader_exec( argv, envp, use_preloader ); + preloader_exec( argv, use_preloader ); } diff --git a/loader/glibc.c b/loader/glibc.c index 0cdf4089e7f..4d15d5c76b6 100644 --- a/loader/glibc.c +++ b/loader/glibc.c @@ -67,6 +67,19 @@ static const char *get_threading(void) return ret ? "wine-pthread" : "wine-kthread"; } +/* build a new full path from the specified path and name */ +static const char *build_new_path( const char *path, const char *name ) +{ + const char *p; + char *ret; + + if (!(p = strrchr( path, '/' ))) return name; + p++; + ret = xmalloc( (p - path) + strlen(name) + 1 ); + memcpy( ret, path, p - path ); + strcpy( ret + (p - path), name ); + return ret; +} /********************************************************************** * main @@ -75,31 +88,22 @@ int main( int argc, char *argv[] ) { const char *loader = getenv( "WINELOADER" ); const char *threads = get_threading(); + const char *new_argv0 = build_new_path( argv[0], threads ); + + wine_init_argv0_path( new_argv0 ); if (loader) { - const char *path; - char *new_name, *new_loader; - - if ((path = strrchr( loader, '/' ))) path++; - else path = loader; - - new_name = xmalloc( (path - loader) + strlen(threads) + 1 ); - memcpy( new_name, loader, path - loader ); - strcpy( new_name + (path - loader), threads ); - /* update WINELOADER with the new name */ - new_loader = xmalloc( sizeof("WINELOADER=") + strlen(new_name) ); + const char *new_name = build_new_path( loader, threads ); + char *new_loader = xmalloc( sizeof("WINELOADER=") + strlen(new_name) ); strcpy( new_loader, "WINELOADER=" ); strcat( new_loader, new_name ); putenv( new_loader ); - wine_exec_wine_binary( new_name, argv, NULL, TRUE ); + loader = new_name; } - else - { - wine_init_argv0_path( argv[0] ); - wine_exec_wine_binary( threads, argv, NULL, TRUE ); - } - fprintf( stderr, "wine: could not exec %s\n", argv[0] ); + + wine_exec_wine_binary( NULL, argv, loader ); + fprintf( stderr, "wine: could not exec %s\n", threads ); exit(1); }