Use special environment variables to transmit the cwd of the various

drives to child processes (based on a patch by Andreas Mohr).
This commit is contained in:
Alexandre Julliard 2000-10-03 04:19:16 +00:00
parent 8b7f04d616
commit aef9a36059
3 changed files with 59 additions and 7 deletions

View File

@ -15,6 +15,7 @@
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -146,6 +147,7 @@ int DRIVE_Init(void)
{
int i, len, count = 0;
char name[] = "Drive A";
char drive_env[] = "=A:";
char path[MAX_PATHNAME_LEN];
char buffer[80];
struct stat drive_stat_buffer;
@ -257,6 +259,14 @@ int DRIVE_Init(void)
}
}
/* get current working directory info for all drives */
for (i = 0; i < MAX_DOS_DRIVES; i++, drive_env[1]++)
{
if (!GetEnvironmentVariableA(drive_env, path, sizeof(path))) continue;
/* sanity check */
if (toupper(path[0]) != drive_env[1] || path[1] != ':') continue;
DRIVE_Chdir( i, path + 2 );
}
return 1;
}
@ -920,6 +930,34 @@ static UINT DRIVE_GetCurrentDirectory( UINT buflen, LPSTR buf )
return ret;
}
/***********************************************************************
* DRIVE_BuildEnv
*
* Build the environment array containing the drives current directories.
* Resulting pointer must be freed with HeapFree.
*/
char *DRIVE_BuildEnv(void)
{
int i, length = 0;
const char *cwd[MAX_DOS_DRIVES];
char *env, *p;
for (i = 0; i < MAX_DOS_DRIVES; i++)
{
if ((cwd[i] = DRIVE_GetDosCwd(i)) && cwd[i][0]) length += strlen(cwd[i]) + 8;
}
if (!(env = HeapAlloc( GetProcessHeap(), 0, length+1 ))) return NULL;
for (i = 0, p = env; i < MAX_DOS_DRIVES; i++)
{
if (cwd[i] && cwd[i][0])
p += sprintf( p, "=%c:=%c:\\%s", 'A'+i, 'A'+i, cwd[i] ) + 1;
}
*p = 0;
return env;
}
/***********************************************************************
* GetDiskFreeSpace16 (KERNEL.422)
*/

View File

@ -50,5 +50,6 @@ extern int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive );
extern int DRIVE_OpenDevice( int drive, int flags );
extern int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD length, BYTE *dataptr, BOOL fake_success );
extern int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD length, BYTE *dataptr, BOOL fake_success );
extern char *DRIVE_BuildEnv(void);
#endif /* __WINE_DRIVE_H */

View File

@ -15,6 +15,7 @@
#include "wine/winbase16.h"
#include "wine/exception.h"
#include "process.h"
#include "drive.h"
#include "main.h"
#include "module.h"
#include "neexe.h"
@ -577,20 +578,24 @@ static char **build_argv( char *cmdline, int reserved )
*
* Build the environment of a new child process.
*/
static char **build_envp( const char *env )
static char **build_envp( const char *env, const char *extra_env )
{
const char *p;
char **envp;
int count;
int count = 0;
for (p = env, count = 0; *p; count++) p += strlen(p) + 1;
if (extra_env) for (p = extra_env; *p; count++) p += strlen(p) + 1;
for (p = env; *p; count++) p += strlen(p) + 1;
count += 3;
if ((envp = malloc( count * sizeof(*envp) )))
{
extern char **environ;
char **envptr = envp;
char **unixptr = environ;
/* first put PATH, HOME and WINEPREFIX from the unix env */
/* first the extra strings */
if (extra_env) for (p = extra_env; *p; p += strlen(p) + 1) *envptr++ = (char *)p;
/* then put PATH, HOME and WINEPREFIX from the unix env */
for (unixptr = environ; unixptr && *unixptr; unixptr++)
if (!memcmp( *unixptr, "PATH=", 5 ) ||
!memcmp( *unixptr, "HOME=", 5 ) ||
@ -665,6 +670,13 @@ static int fork_and_exec( const char *filename, char *cmdline,
{
int fd[2];
int pid, err;
char *extra_env = NULL;
if (!env)
{
env = GetEnvironmentStringsA();
extra_env = DRIVE_BuildEnv();
}
if (pipe(fd) == -1)
{
@ -675,7 +687,7 @@ static int fork_and_exec( const char *filename, char *cmdline,
if (!(pid = fork())) /* child */
{
char **argv = build_argv( cmdline, filename ? 0 : 2 );
char **envp = build_envp( env );
char **envp = build_envp( env, extra_env );
close( fd[0] );
if (newdir) chdir(newdir);
@ -701,6 +713,7 @@ static int fork_and_exec( const char *filename, char *cmdline,
}
if (pid == -1) FILE_SetDosError();
close( fd[0] );
if (extra_env) HeapFree( GetProcessHeap(), 0, extra_env );
return pid;
}
@ -784,7 +797,7 @@ BOOL PROCESS_Create( HFILE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
/* fork and execute */
pid = fork_and_exec( unixfilename, cmd_line, env ? env : GetEnvironmentStringsA(), unixdir );
pid = fork_and_exec( unixfilename, cmd_line, env, unixdir );
SERVER_START_REQ
{