kernel32: Call build_envp in the parent process so that it can use the Win32 heap.
This commit is contained in:
parent
da03d9355d
commit
a4e688218c
|
@ -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
|
* 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 char **build_envp( const WCHAR *envW )
|
||||||
{
|
{
|
||||||
|
static const char * const unix_vars[] = { "PATH", "TEMP", "TMP", "HOME" };
|
||||||
|
|
||||||
const WCHAR *end;
|
const WCHAR *end;
|
||||||
char **envp;
|
char **envp;
|
||||||
char *env, *p;
|
char *env, *p;
|
||||||
int count = 0, length;
|
int count = 0, length;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
for (end = envW; *end; count++) end += strlenW(end) + 1;
|
for (end = envW; *end; count++) end += strlenW(end) + 1;
|
||||||
end++;
|
end++;
|
||||||
length = WideCharToMultiByte( CP_UNIXCP, 0, envW, end - envW, NULL, 0, NULL, NULL );
|
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 );
|
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 **envptr = envp;
|
||||||
|
char *dst = (char *)(envp + count);
|
||||||
|
|
||||||
/* some variables must not be modified, so we get them directly from the unix env */
|
/* 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 );
|
for (i = 0; i < sizeof(unix_vars)/sizeof(unix_vars[0]); i++)
|
||||||
if ((p = getenv("TEMP"))) *envptr++ = alloc_env_string( "TEMP=", p );
|
{
|
||||||
if ((p = getenv("TMP"))) *envptr++ = alloc_env_string( "TMP=", p );
|
if (!(p = getenv(unix_vars[i]))) continue;
|
||||||
if ((p = getenv("HOME"))) *envptr++ = alloc_env_string( "HOME=", p );
|
*envptr++ = strcpy( dst, unix_vars[i] );
|
||||||
|
strcat( dst, "=" );
|
||||||
|
strcat( dst, p );
|
||||||
|
dst += strlen(dst) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* now put the Windows environment strings */
|
/* now put the Windows environment strings */
|
||||||
for (p = env; *p; p += strlen(p) + 1)
|
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, "WINEPRELOADRESERVE=", sizeof("WINEPRELOADRESERVE=")-1 )) continue;
|
||||||
if (!strncmp( p, "WINESERVERSOCKET=", sizeof("WINESERVERSOCKET=")-1 )) continue;
|
if (!strncmp( p, "WINESERVERSOCKET=", sizeof("WINESERVERSOCKET=")-1 )) continue;
|
||||||
if (is_special_env_var( p )) /* prefix it with "WINE" */
|
if (is_special_env_var( p )) /* prefix it with "WINE" */
|
||||||
*envptr++ = alloc_env_string( "WINE", p );
|
{
|
||||||
|
*envptr++ = strcpy( dst, "WINE" );
|
||||||
|
strcat( dst, p );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
*envptr++ = p;
|
{
|
||||||
|
*envptr++ = strcpy( dst, p );
|
||||||
|
}
|
||||||
|
dst += strlen(dst) + 1;
|
||||||
}
|
}
|
||||||
*envptr = 0;
|
*envptr = 0;
|
||||||
}
|
}
|
||||||
|
HeapFree( GetProcessHeap(), 0, env );
|
||||||
return envp;
|
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 fd[2], stdin_fd = -1, stdout_fd = -1;
|
||||||
int pid, err;
|
int pid, err;
|
||||||
char **argv;
|
char **argv, **envp;
|
||||||
|
|
||||||
if (!env) env = GetEnvironmentStringsW();
|
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 );
|
argv = build_argv( cmdline, 0 );
|
||||||
|
envp = build_envp( env );
|
||||||
|
|
||||||
if (!(pid = fork())) /* child */
|
if (!(pid = fork())) /* child */
|
||||||
{
|
{
|
||||||
char **envp = build_envp( env );
|
|
||||||
|
|
||||||
close( fd[0] );
|
close( fd[0] );
|
||||||
|
|
||||||
if (flags & (CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE | DETACHED_PROCESS))
|
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);
|
_exit(1);
|
||||||
}
|
}
|
||||||
HeapFree( GetProcessHeap(), 0, argv );
|
HeapFree( GetProcessHeap(), 0, argv );
|
||||||
|
HeapFree( GetProcessHeap(), 0, envp );
|
||||||
if (stdin_fd != -1) close( stdin_fd );
|
if (stdin_fd != -1) close( stdin_fd );
|
||||||
if (stdout_fd != -1) close( stdout_fd );
|
if (stdout_fd != -1) close( stdout_fd );
|
||||||
close( fd[1] );
|
close( fd[1] );
|
||||||
|
|
Loading…
Reference in New Issue