From daeccba704e24167f4ba08709a83014fb9ca60b8 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 11 Nov 2003 22:21:29 +0000 Subject: [PATCH] Moved the exec_wine_binary function to the wine library, and use it to exec the wineserver too. --- dlls/kernel/Makefile.in | 2 +- dlls/kernel/process.c | 58 ++++++----------------------------------- dlls/ntdll/Makefile.in | 2 +- dlls/ntdll/server.c | 24 +++++------------ include/wine/library.h | 3 ++- libs/wine/Makefile.in | 2 +- libs/wine/config.c | 56 +++++++++++++++++++++++++++++++++++---- libs/wine/loader.c | 4 +-- libs/wine/wine.def | 3 ++- 9 files changed, 73 insertions(+), 81 deletions(-) diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in index 99132a70166..34c9804e2ad 100644 --- a/dlls/kernel/Makefile.in +++ b/dlls/kernel/Makefile.in @@ -1,4 +1,4 @@ -EXTRADEFS = -D_KERNEL32_ -DBINDIR="\"$(bindir)\"" -DETCDIR="\"$(sysconfdir)\"" +EXTRADEFS = -D_KERNEL32_ -DETCDIR="\"$(sysconfdir)\"" TOPSRCDIR = @top_srcdir@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index f86d653daa6..1a8f9854fcb 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -1064,54 +1064,6 @@ static char **build_envp( const WCHAR *envW, const WCHAR *extra_envW ) } -/*********************************************************************** - * exec_wine_binary - * - * Locate the Wine binary to exec for a new Win32 process. - */ -static void exec_wine_binary( char **argv, char **envp ) -{ - const char *path, *pos, *ptr; - - /* first, try for a WINELOADER environment variable */ - argv[0] = getenv("WINELOADER"); - if (argv[0]) - execve( argv[0], argv, envp ); - - /* next, try bin directory */ - argv[0] = BINDIR "/wine"; - execve( argv[0], argv, envp ); - - /* now try the path of argv0 of the current binary */ - if ((path = wine_get_argv0_path())) - { - if (!(argv[0] = malloc( strlen(path) + sizeof("wine") ))) return; - strcpy( argv[0], path ); - strcat( argv[0], "wine" ); - execve( argv[0], argv, envp ); - free( argv[0] ); - } - - /* now search in the Unix path */ - if ((path = getenv( "PATH" ))) - { - if (!(argv[0] = malloc( strlen(path) + 6 ))) return; - pos = path; - for (;;) - { - while (*pos == ':') pos++; - if (!*pos) break; - if (!(ptr = strchr( pos, ':' ))) ptr = pos + strlen(pos); - memcpy( argv[0], pos, ptr - pos ); - strcpy( argv[0] + (ptr - pos), "/wine" ); - execve( argv[0], argv, envp ); - pos = ptr; - } - } - free( argv[0] ); -} - - /*********************************************************************** * fork_and_exec * @@ -1280,8 +1232,14 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW if (unixdir) chdir(unixdir); - if (argv && envp) exec_wine_binary( argv, envp ); - + if (argv && envp) + { + /* first, try for a WINELOADER environment variable */ + argv[0] = getenv("WINELOADER"); + if (argv[0]) execve( argv[0], argv, envp ); + /* now use the standard search strategy */ + wine_exec_wine_binary( NULL, argv, envp ); + } err = errno; write( execfd[1], &err, sizeof(err) ); _exit(1); diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in index b907af038a0..ddc4b8261bd 100644 --- a/dlls/ntdll/Makefile.in +++ b/dlls/ntdll/Makefile.in @@ -1,4 +1,4 @@ -EXTRADEFS = -D_NTSYSTEM_ -DBINDIR="\"$(bindir)\"" +EXTRADEFS = -D_NTSYSTEM_ TOPSRCDIR = @top_srcdir@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index c6bcb0ad718..2226819e959 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -466,7 +466,8 @@ static void start_server( const char *oldcwd ) { static int started; /* we only try once */ char *path, *p; - const char *argv0_path; + char *argv[2]; + if (!started) { int status; @@ -488,23 +489,10 @@ static void start_server( const char *oldcwd ) fatal_perror( "could not exec the server '%s'\n" " specified in the WINESERVER environment variable", p ); } - - /* first try the installation dir */ - execl( BINDIR "/wineserver", "wineserver", NULL ); - - /* now try the dir we were launched from */ - if ((argv0_path = wine_get_argv0_path())) - { - if (!(path = malloc( strlen(argv0_path) + sizeof("wineserver") ))) - fatal_error( "out of memory\n" ); - strcpy( path, argv0_path ); - strcat( path, "wineserver" ); - execl( path, path, NULL ); - free(path); - } - - /* finally try the path */ - execlp( "wineserver", "wineserver", NULL ); + /* now use the standard search strategy */ + argv[0] = "wineserver"; + argv[1] = NULL; + wine_exec_wine_binary( "wineserver", argv, NULL ); fatal_error( "could not exec wineserver\n" ); } waitpid( pid, &status, 0 ); diff --git a/include/wine/library.h b/include/wine/library.h index 68ba2c71b22..7aebaf209fe 100644 --- a/include/wine/library.h +++ b/include/wine/library.h @@ -32,7 +32,8 @@ 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 const char *wine_get_argv0_path(void); +extern void wine_init_argv0_path( const char *argv0 ); +extern void wine_exec_wine_binary( const char *name, char **argv, char **envp ); /* dll loading */ diff --git a/libs/wine/Makefile.in b/libs/wine/Makefile.in index 65a6051a625..4265ae3efa9 100644 --- a/libs/wine/Makefile.in +++ b/libs/wine/Makefile.in @@ -4,7 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ LIBRARY = wine SOVERSION = 1 -EXTRADEFS = -D__WINESRC__ -DDLLDIR="\"$(dlldir)\"" +EXTRADEFS = -D__WINESRC__ -DBINDIR="\"$(bindir)\"" -DDLLDIR="\"$(dlldir)\"" EXTRALIBS = $(LIBPORT) @DLLIBS@ @CRTLIBS@ C_SRCS = \ diff --git a/libs/wine/config.c b/libs/wine/config.c index e4ef9d54fdc..6ea0f8becee 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c @@ -42,6 +42,7 @@ static char *config_dir; static char *server_dir; static char *user_name; static char *argv0_path; +static char *argv0_name; #ifdef __GNUC__ static void fatal_error( const char *err, ... ) __attribute__((noreturn,format(printf,1,2))); @@ -181,14 +182,18 @@ static void init_paths(void) } /* initialize the argv0 path */ -void init_argv0_path( const char *argv0 ) +void wine_init_argv0_path( const char *argv0 ) { size_t size, len; const char *p; char *cwd; if (!(p = strrchr( argv0, '/' ))) - return; /* if argv0 doesn't contain a path, don't do anything */ + { + argv0_name = xstrdup( argv0 ); + return; /* if argv0 doesn't contain a path, don't store any path */ + } + else argv0_name = xstrdup( p + 1 ); len = p - argv0 + 1; if (argv0[0] == '/') /* absolute path */ @@ -238,8 +243,49 @@ const char *wine_get_user_name(void) return user_name; } -/* return the path of argv[0], including a trailing slash */ -const char *wine_get_argv0_path(void) +/* exec a wine internal binary (either the wine loader or the wine server) */ +/* if name is null, default to the name of the current binary */ +void wine_exec_wine_binary( const char *name, char **argv, char **envp ) { - return argv0_path; + const char *path, *pos, *ptr; + extern char **environ; + + if (!envp) envp = environ; + if (!name) name = argv0_name; + + /* first, try bin directory */ + argv[0] = xmalloc( sizeof(BINDIR "/") + strlen(name) ); + strcpy( argv[0], BINDIR "/" ); + strcat( argv[0], name ); + execve( argv[0], argv, envp ); + free( argv[0] ); + + /* now try the path of argv0 of the current binary */ + if (argv0_path) + { + argv[0] = xmalloc( strlen(argv0_path) + strlen(name) + 1 ); + strcpy( argv[0], argv0_path ); + strcat( argv[0], name ); + execve( argv[0], argv, envp ); + free( argv[0] ); + } + + /* now search in the Unix path */ + if ((path = getenv( "PATH" ))) + { + argv[0] = xmalloc( strlen(path) + strlen(name) + 2 ); + pos = path; + for (;;) + { + while (*pos == ':') pos++; + if (!*pos) break; + if (!(ptr = strchr( pos, ':' ))) ptr = pos + strlen(pos); + memcpy( argv[0], pos, ptr - pos ); + strcpy( argv[0] + (ptr - pos), "/" ); + strcat( argv[0] + (ptr - pos), name ); + execve( argv[0], argv, envp ); + pos = ptr; + } + free( argv[0] ); + } } diff --git a/libs/wine/loader.c b/libs/wine/loader.c index d3b87135416..3a8b5a2e0a1 100644 --- a/libs/wine/loader.c +++ b/libs/wine/loader.c @@ -47,8 +47,6 @@ char **__wine_main_argv = NULL; WCHAR **__wine_main_wargv = NULL; char **__wine_main_environ = NULL; -extern void init_argv0_path( const char *argv0 ); /* config.c */ - #define MAX_DLLS 100 static struct @@ -426,7 +424,7 @@ void wine_init( int argc, char *argv[], char *error, int error_size ) void (*init_func)(void); build_dll_path(); - init_argv0_path( argv[0] ); + wine_init_argv0_path( argv[0] ); __wine_main_argc = argc; __wine_main_argv = argv; __wine_main_environ = environ; diff --git a/libs/wine/wine.def b/libs/wine/wine.def index e7725f42c77..68159552de4 100644 --- a/libs/wine/wine.def +++ b/libs/wine/wine.def @@ -30,7 +30,7 @@ EXPORTS wine_dll_unload wine_dlopen wine_dlsym - wine_get_argv0_path + wine_exec_wine_binary wine_get_config_dir wine_get_cs wine_get_ds @@ -41,6 +41,7 @@ EXPORTS wine_get_ss wine_get_user_name wine_init + wine_init_argv0_path wine_ldt_alloc_entries wine_ldt_alloc_fs wine_ldt_copy