Alexandre Julliard : kernel32: Call build_envp in the parent process so that it can use the Win32 heap.

Alexandre Julliard julliard at winehq.org
Fri Oct 31 09:24:19 CDT 2008


Module: wine
Branch: master
Commit: a4e688218c8a092b785f153525a1d841aaf6080a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a4e688218c8a092b785f153525a1d841aaf6080a

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Oct 31 14:55:33 2008 +0100

kernel32: Call build_envp in the parent process so that it can use the Win32 heap.

---

 dlls/kernel32/process.c |   61 +++++++++++++++++++++++++++-------------------
 1 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 4524e65..dcf4ce8 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1171,47 +1171,51 @@ 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
  *
  * Build the environment of a new child process.
  */
 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" */
+
+    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 = malloc( count * sizeof(*envp) )))
+    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] );




More information about the wine-cvs mailing list