From a4e688218c8a092b785f153525a1d841aaf6080a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 31 Oct 2008 14:55:33 +0100 Subject: [PATCH] kernel32: Call build_envp in the parent process so that it can use the Win32 heap. --- dlls/kernel32/process.c | 61 ++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 4524e65d037..dcf4ce8d52c 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -1170,19 +1170,6 @@ static char **build_argv( const WCHAR *cmdlineW, int reserved ) } -/*********************************************************************** - * alloc_env_string - * - * Allocate an environment string; helper for build_envp - */ -static char *alloc_env_string( const char *name, const char *value ) -{ - char *ret = malloc( strlen(name) + strlen(value) + 1 ); - strcpy( ret, name ); - strcat( ret, value ); - return ret; -} - /*********************************************************************** * build_envp * @@ -1190,28 +1177,45 @@ static char *alloc_env_string( const char *name, const char *value ) */ static char **build_envp( const WCHAR *envW ) { + static const char * const unix_vars[] = { "PATH", "TEMP", "TMP", "HOME" }; + const WCHAR *end; char **envp; char *env, *p; int count = 0, length; + unsigned int i; for (end = envW; *end; count++) end += strlenW(end) + 1; end++; length = WideCharToMultiByte( CP_UNIXCP, 0, envW, end - envW, NULL, 0, NULL, NULL ); - if (!(env = malloc( length ))) return NULL; + if (!(env = HeapAlloc( GetProcessHeap(), 0, length ))) return NULL; WideCharToMultiByte( CP_UNIXCP, 0, envW, end - envW, env, length, NULL, NULL ); - count += 4; + for (p = env; *p; p += strlen(p) + 1) + if (is_special_env_var( p )) length += 4; /* prefix it with "WINE" */ - if ((envp = malloc( count * sizeof(*envp) ))) + for (i = 0; i < sizeof(unix_vars)/sizeof(unix_vars[0]); i++) + { + if (!(p = getenv(unix_vars[i]))) continue; + length += strlen(unix_vars[i]) + strlen(p) + 2; + count++; + } + + if ((envp = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*envp) + length ))) { char **envptr = envp; + char *dst = (char *)(envp + count); /* some variables must not be modified, so we get them directly from the unix env */ - if ((p = getenv("PATH"))) *envptr++ = alloc_env_string( "PATH=", p ); - if ((p = getenv("TEMP"))) *envptr++ = alloc_env_string( "TEMP=", p ); - if ((p = getenv("TMP"))) *envptr++ = alloc_env_string( "TMP=", p ); - if ((p = getenv("HOME"))) *envptr++ = alloc_env_string( "HOME=", p ); + for (i = 0; i < sizeof(unix_vars)/sizeof(unix_vars[0]); i++) + { + if (!(p = getenv(unix_vars[i]))) continue; + *envptr++ = strcpy( dst, unix_vars[i] ); + strcat( dst, "=" ); + strcat( dst, p ); + dst += strlen(dst) + 1; + } + /* now put the Windows environment strings */ for (p = env; *p; p += strlen(p) + 1) { @@ -1219,12 +1223,19 @@ static char **build_envp( const WCHAR *envW ) if (!strncmp( p, "WINEPRELOADRESERVE=", sizeof("WINEPRELOADRESERVE=")-1 )) continue; if (!strncmp( p, "WINESERVERSOCKET=", sizeof("WINESERVERSOCKET=")-1 )) continue; if (is_special_env_var( p )) /* prefix it with "WINE" */ - *envptr++ = alloc_env_string( "WINE", p ); + { + *envptr++ = strcpy( dst, "WINE" ); + strcat( dst, p ); + } else - *envptr++ = p; + { + *envptr++ = strcpy( dst, p ); + } + dst += strlen(dst) + 1; } *envptr = 0; } + HeapFree( GetProcessHeap(), 0, env ); return envp; } @@ -1239,7 +1250,7 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline, const WCHA { int fd[2], stdin_fd = -1, stdout_fd = -1; int pid, err; - char **argv; + char **argv, **envp; if (!env) env = GetEnvironmentStringsW(); @@ -1272,11 +1283,10 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline, const WCHA } argv = build_argv( cmdline, 0 ); + envp = build_envp( env ); if (!(pid = fork())) /* child */ { - char **envp = build_envp( env ); - close( fd[0] ); if (flags & (CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE | DETACHED_PROCESS)) @@ -1322,6 +1332,7 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline, const WCHA _exit(1); } HeapFree( GetProcessHeap(), 0, argv ); + HeapFree( GetProcessHeap(), 0, envp ); if (stdin_fd != -1) close( stdin_fd ); if (stdout_fd != -1) close( stdout_fd ); close( fd[1] );