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:
parent
8b7f04d616
commit
aef9a36059
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,10 +687,10 @@ 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);
|
||||
if (newdir) chdir(newdir);
|
||||
|
||||
if (argv && envp)
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue