Moved the exec_wine_binary function to the wine library, and use it to exec the wineserver too.
diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in index 99132a7..34c9804 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 f86d653..1a8f985 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c
@@ -1065,54 +1065,6 @@ /*********************************************************************** - * 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 * * Fork and exec a new Unix binary, checking for errors. @@ -1280,8 +1232,14 @@ 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 b907af0..ddc4b82 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 c6bcb0a..2226819 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c
@@ -466,7 +466,8 @@ { 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 @@ 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 68ba2c7..7aebaf2 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 65a6051..4265ae3 100644 --- a/libs/wine/Makefile.in +++ b/libs/wine/Makefile.in
@@ -4,7 +4,7 @@ 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 e4ef9d5..6ea0f8b 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c
@@ -42,6 +42,7 @@ 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 @@ } /* 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 @@ 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 d3b8713..3a8b5a2 100644 --- a/libs/wine/loader.c +++ b/libs/wine/loader.c
@@ -47,8 +47,6 @@ 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 (*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 e7725f4..6815955 100644 --- a/libs/wine/wine.def +++ b/libs/wine/wine.def
@@ -30,7 +30,7 @@ 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 @@ wine_get_ss wine_get_user_name wine_init + wine_init_argv0_path wine_ldt_alloc_entries wine_ldt_alloc_fs wine_ldt_copy