mirror of
https://github.com/reactos/reactos.git
synced 2025-01-15 18:43:27 +00:00
correct some bugs in spawn... functions
svn path=/trunk/; revision=1591
This commit is contained in:
parent
c8f92d26a9
commit
65249c23ae
5 changed files with 119 additions and 32 deletions
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.43 2001/01/17 17:00:22 jean Exp $
|
# $Id: makefile,v 1.44 2001/02/01 16:44:19 jean Exp $
|
||||||
#
|
#
|
||||||
# ReactOS Operating System
|
# ReactOS Operating System
|
||||||
#
|
#
|
||||||
|
@ -107,7 +107,7 @@ STDLIB_OBJECTS = stdlib/abort.o stdlib/abs.o stdlib/atexit.o stdlib/atof.o stdli
|
||||||
|
|
||||||
SIGNAL_OBJECTS = signal/signal.o signal/xcptfil.o signal/xcptinfo.o
|
SIGNAL_OBJECTS = signal/signal.o signal/xcptfil.o signal/xcptinfo.o
|
||||||
|
|
||||||
PROCESS_OBJECTS = process/_cwait.o process/dll.o process/spawnl.o process/spawnlp.o process/spawnlpe.o process/spawnvpe.o process/spawnvp.o \
|
PROCESS_OBJECTS = process/_cwait.o process/dll.o process/spawnl.o process/spawnlp.o process/spawnlpe.o process/spawnvp.o \
|
||||||
process/spawnv.o process/spawnve.o process/spawnle.o process/execl.o process/execlp.o process/execlpe.o \
|
process/spawnv.o process/spawnve.o process/spawnle.o process/execl.o process/execlp.o process/execlpe.o \
|
||||||
process/execvpe.o process/execvp.o process/execv.o process/execle.o process/_system.o\
|
process/execvpe.o process/execvp.o process/execv.o process/execle.o process/_system.o\
|
||||||
process/execve.o process/threadid.o process/thread.o process/procid.o
|
process/execve.o process/threadid.o process/thread.o process/procid.o
|
||||||
|
|
|
@ -22,5 +22,5 @@ int _cwait (int* pnStatus, int hProc, int nAction)
|
||||||
|
|
||||||
if ( !GetExitCodeProcess((void *)hProc,pnStatus) )
|
if ( !GetExitCodeProcess((void *)hProc,pnStatus) )
|
||||||
return -1;
|
return -1;
|
||||||
return *pnStatus;
|
return hProc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,9 @@ int _spawnl(int nMode, const char* szPath, const char* szArgv0,...)
|
||||||
{
|
{
|
||||||
char *szArg[100];
|
char *szArg[100];
|
||||||
const char *a;
|
const char *a;
|
||||||
int i = 0;
|
int i = 1;
|
||||||
va_list l = 0;
|
va_list l = 0;
|
||||||
|
szArg[0]=szArgv0;
|
||||||
va_start(l,szArgv0);
|
va_start(l,szArgv0);
|
||||||
do {
|
do {
|
||||||
a = va_arg(l,const char *);
|
a = va_arg(l,const char *);
|
||||||
|
|
|
@ -8,23 +8,22 @@ int _spawnle(int mode, const char *path, const char *szArgv0, ... /*, const char
|
||||||
char *szArg[100];
|
char *szArg[100];
|
||||||
char *a;
|
char *a;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int i = 0;
|
int i = 1;
|
||||||
va_list l = 0;
|
va_list l = 0;
|
||||||
|
szArg[0]=szArgv0;
|
||||||
va_start(l,szArgv0);
|
va_start(l,szArgv0);
|
||||||
do {
|
do {
|
||||||
a = (char *)va_arg(l,const char *);
|
a = (char *)va_arg(l,const char *);
|
||||||
szArg[i++] = (char *)a;
|
szArg[i++] = (char *)a;
|
||||||
} while ( a != NULL && i < 100 );
|
} while ( a != NULL && i < 100 );
|
||||||
|
|
||||||
|
if(a != NULL)
|
||||||
// szArg0 is passed and not environment if there is only one parameter;
|
{
|
||||||
|
// __set_errno(E2BIG);
|
||||||
if ( i >=2 ) {
|
return -1;
|
||||||
ptr = szArg[i-2];
|
|
||||||
szArg[i-2] = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
ptr = NULL;
|
ptr = (char *)va_arg(l,const char *);
|
||||||
|
|
||||||
return _spawnve(mode, path, (char * const *)szArg, (char * const *)ptr);
|
return _spawnve(mode, path, (char * const *)szArg, (char * const *)ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,10 @@ int _fileinfo_dll = 0;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
direct_exec_tail(const char *program, const char *args,
|
direct_exec_tail(const char *program, const char *args,
|
||||||
char * const envp[])
|
char * const envp[],
|
||||||
|
PROCESS_INFORMATION *ProcessInformation)
|
||||||
{
|
{
|
||||||
|
|
||||||
static PROCESS_INFORMATION ProcessInformation;
|
|
||||||
static STARTUPINFO StartupInfo;
|
static STARTUPINFO StartupInfo;
|
||||||
|
|
||||||
StartupInfo.cb = sizeof(STARTUPINFO);
|
StartupInfo.cb = sizeof(STARTUPINFO);
|
||||||
|
@ -49,14 +49,17 @@ direct_exec_tail(const char *program, const char *args,
|
||||||
StartupInfo.cbReserved2 = 0;
|
StartupInfo.cbReserved2 = 0;
|
||||||
|
|
||||||
|
|
||||||
if ( CreateProcessA((char *)program,(char *)args,NULL,NULL,FALSE,0,(char **)envp,NULL,&StartupInfo,&ProcessInformation) ) {
|
if (! CreateProcessA((char *)program,(char *)args,NULL,NULL,FALSE,0,(char **)envp,NULL,&StartupInfo,ProcessInformation) )
|
||||||
return -1;
|
{
|
||||||
|
__set_errno( GetLastError() );
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessInformation.dwProcessId;
|
return (int)ProcessInformation->hProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vdm_exec(const char *program, char **argv, char **envp)
|
static int vdm_exec(const char *program, char **argv, char **envp,
|
||||||
|
PROCESS_INFORMATION *ProcessInformation)
|
||||||
{
|
{
|
||||||
static char args[1024];
|
static char args[1024];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -69,24 +72,29 @@ static int vdm_exec(const char *program, char **argv, char **envp)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return direct_exec_tail(program,args,envp);
|
return direct_exec_tail(program,args,envp,ProcessInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int go32_exec(const char *program, char **argv, char **envp)
|
static int go32_exec(const char *program, char **argv, char **envp,
|
||||||
|
PROCESS_INFORMATION *ProcessInformation)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
static char args[1024];
|
static char args[1024];
|
||||||
|
static char envblock[2048];
|
||||||
|
char * penvblock;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
|
||||||
args[0] = 0;
|
envblock[0] = 0;
|
||||||
|
penvblock=envblock;
|
||||||
|
|
||||||
while(argv[i] != NULL ) {
|
while(envp[i] != NULL ) {
|
||||||
strcat(args,envp[i]);
|
strcat(penvblock,envp[i]);
|
||||||
strcat(args," ");
|
penvblock+=strlen(envp[i])+1;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
penvblock[0]=0;
|
||||||
|
|
||||||
args[0] = 0;
|
args[0] = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -96,11 +104,12 @@ static int go32_exec(const char *program, char **argv, char **envp)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return direct_exec_tail(program,args,envp);
|
return direct_exec_tail(program,args,envp,ProcessInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
command_exec(const char *program, char **argv, char **envp)
|
command_exec(const char *program, char **argv, char **envp,
|
||||||
|
PROCESS_INFORMATION *ProcessInformation)
|
||||||
{
|
{
|
||||||
static char args[1024];
|
static char args[1024];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -116,11 +125,12 @@ command_exec(const char *program, char **argv, char **envp)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return direct_exec_tail(program,args,envp);
|
return direct_exec_tail(program,args,envp,ProcessInformation);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int script_exec(const char *program, char **argv, char **envp)
|
static int script_exec(const char *program, char **argv, char **envp,
|
||||||
|
PROCESS_INFORMATION *ProcessInformation)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -132,10 +142,13 @@ static int script_exec(const char *program, char **argv, char **envp)
|
||||||
executable from one of the shells used on MSDOS. */
|
executable from one of the shells used on MSDOS. */
|
||||||
static struct {
|
static struct {
|
||||||
const char *extension;
|
const char *extension;
|
||||||
int (*interp)(const char *, char **, char **);
|
int (*interp)(const char *, char **, char **,
|
||||||
|
PROCESS_INFORMATION *);
|
||||||
} interpreters[] = {
|
} interpreters[] = {
|
||||||
{ ".com", vdm_exec },
|
{ ".com", vdm_exec },
|
||||||
{ ".exe", go32_exec },
|
{ ".exe", go32_exec },
|
||||||
|
{ ".dll", go32_exec },
|
||||||
|
{ ".cmd", command_exec },
|
||||||
{ ".bat", command_exec },
|
{ ".bat", command_exec },
|
||||||
{ ".btm", command_exec },
|
{ ".btm", command_exec },
|
||||||
{ ".sh", script_exec }, /* for compatibility with ms_sh */
|
{ ".sh", script_exec }, /* for compatibility with ms_sh */
|
||||||
|
@ -159,6 +172,7 @@ static struct {
|
||||||
int _spawnve(int mode, const char *path, char *const argv[], char *const envp[])
|
int _spawnve(int mode, const char *path, char *const argv[], char *const envp[])
|
||||||
{
|
{
|
||||||
/* This is the one that does the work! */
|
/* This is the one that does the work! */
|
||||||
|
PROCESS_INFORMATION ProcessInformation;
|
||||||
union { char *const *x; char **p; } u;
|
union { char *const *x; char **p; } u;
|
||||||
int i = -1;
|
int i = -1;
|
||||||
char **argvp;
|
char **argvp;
|
||||||
|
@ -237,13 +251,86 @@ int _spawnve(int mode, const char *path, char *const argv[], char *const envp[])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
errno = e;
|
errno = e;
|
||||||
i = interpreters[i].interp(rpath, argvp, envpp);
|
i = interpreters[i].interp(rpath, argvp, envpp, &ProcessInformation);
|
||||||
if (mode == P_OVERLAY)
|
if (mode == P_OVERLAY)
|
||||||
exit(i);
|
exit(i);
|
||||||
|
if (mode == P_WAIT)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(ProcessInformation.hProcess,INFINITE);
|
||||||
|
GetExitCodeProcess(ProcessInformation.hProcess,&i);
|
||||||
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char * find_exec(char * path,char *rpath)
|
||||||
|
{
|
||||||
|
char *rp, *rd=0;
|
||||||
|
int i;
|
||||||
|
int is_dir = 0;
|
||||||
|
int found = 0;
|
||||||
|
if (path == 0 )
|
||||||
|
return 0;
|
||||||
|
if (strlen(path) > FILENAME_MAX - 1)
|
||||||
|
return path;
|
||||||
|
|
||||||
|
/* copy path in rpath */
|
||||||
|
for (rd=path,rp=rpath; *rd; *rp++ = *rd++)
|
||||||
|
;
|
||||||
|
*rp = 0;
|
||||||
|
/* try first with the name as is */
|
||||||
|
for (i=0; interpreters[i].extension; i++)
|
||||||
|
{
|
||||||
|
strcpy(rp, interpreters[i].extension);
|
||||||
|
if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0)))
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
/* search in the PATH */
|
||||||
|
char winpath[MAX_PATH];
|
||||||
|
if( GetEnvironmentVariableA("PATH",winpath,MAX_PATH))
|
||||||
|
{
|
||||||
|
char *ep=winpath;
|
||||||
|
while( *ep)
|
||||||
|
{
|
||||||
|
if(*ep == ';') ep++;
|
||||||
|
rp=rpath;
|
||||||
|
for ( ; *ep && (*ep != ';') ; *rp++ = *ep++)
|
||||||
|
;
|
||||||
|
*rp++='/';
|
||||||
|
for (rd=path ; *rd ; *rp++ = *rd++)
|
||||||
|
;
|
||||||
|
|
||||||
|
for (i=0; interpreters[i].extension; i++)
|
||||||
|
{
|
||||||
|
strcpy(rp, interpreters[i].extension);
|
||||||
|
if (_access(rpath, F_OK) == 0 && !(is_dir = (_access(rpath, D_OK) == 0)))
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
return path;
|
||||||
|
|
||||||
|
return rpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _spawnvpe(int nMode, const char* szPath, char* const* szaArgv, char* const* szaEnv)
|
||||||
|
{
|
||||||
|
char rpath[FILENAME_MAX];
|
||||||
|
|
||||||
|
return _spawnve(nMode, find_exec(szPath,rpath), szaArgv, szaEnv);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue