Merged all exec* and spawn* functions in one source file.

Reduced some overhead.

svn path=/trunk/; revision=3682
This commit is contained in:
Hartmut Birr 2002-10-31 07:26:08 +00:00
parent ad6fb31ad3
commit 9b875ab82c
2 changed files with 480 additions and 17 deletions

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.24 2002/10/26 00:32:17 chorns Exp $
# $Id: Makefile,v 1.25 2002/10/31 07:26:08 hbirr Exp $
PATH_TO_TOP = ../..
@ -227,23 +227,8 @@ OBJECTS_PROCESS = \
process/_cwait.o \
process/_system.o \
process/dll.o \
process/execl.o \
process/execle.o \
process/execlp.o \
process/execlpe.o \
process/execv.o \
process/execve.o \
process/execvp.o \
process/execvpe.o \
process/process.o \
process/procid.o \
process/spawnl.o \
process/spawnle.o \
process/spawnlp.o \
process/spawnlpe.o \
process/spawnv.o \
process/spawnve.o \
process/spawnvp.o \
process/spawnvpe.o \
process/thread.o \
process/threadid.o

View file

@ -0,0 +1,478 @@
/* $Id: process.c,v 1.1 2002/10/31 07:26:08 hbirr Exp $ */
#include <windows.h>
#include <msvcrt/process.h>
#include <msvcrt/stdlib.h>
#include <msvcrt/fcntl.h>
#include <msvcrt/errno.h>
#define NDEBUG
#include <msvcrt/msvcrtdbg.h>
extern int maxfno;
static char*
argvtos(char* const* argv, char delim)
{
int i, len;
char *ptr, *str;
if (argv == NULL)
return NULL;
for (i = 0, len = 0; argv[i]; i++)
{
len += strlen(argv[i]) + 1;
}
str = ptr = (char*) malloc(len + 1);
if (str == NULL)
return NULL;
for(i = 0; argv[i]; i++)
{
len = strlen(argv[i]);
memcpy(ptr, argv[i], len);
ptr += len;
*ptr++ = delim;
}
*ptr = 0;
return str;
}
static char*
valisttos(const char* arg0, va_list alist, char delim)
{
va_list alist2 = alist;
char *ptr, *str;
int len;
if (arg0 == NULL)
return NULL;
ptr = (char*)arg0;
len = 0;
do
{
len += strlen(ptr) + 1;
ptr = va_arg(alist, char*);
}
while(ptr != NULL);
str = (char*) malloc(len + 1);
if (str == NULL)
return NULL;
ptr = str;
do
{
len = strlen(arg0);
memcpy(ptr, arg0, len);
*ptr++ = delim;
arg0 = va_arg(alist2, char*);
}
while(arg0 != NULL);
*ptr = 0;
return str;
}
static int
do_spawn(int mode, const char* cmdname, const char* args, const char* envp)
{
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
char* fmode;
HANDLE* hFile;
int i, last;
BOOL bResult;
DWORD dwExitCode;
DWORD dwError;
DPRINT("do_spawn('%s')\n", cmdname);
if (mode != _P_NOWAIT && mode != _P_NOWAITO && mode != _P_WAIT && mode != _P_DETACH && mode != _P_OVERLAY)
{
errno = EINVAL;
return -1;
}
if (0 != _access(cmdname, F_OK))
{
errno = ENOENT;
return -1;
}
if (0 == _access(cmdname, D_OK))
{
errno = EISDIR;
return -1;
}
memset (&StartupInfo, 0, sizeof(STARTUPINFO));
StartupInfo.cb = sizeof(STARTUPINFO);
for (last = i = 0; i < maxfno; i++)
{
if ((void*)-1 != _get_osfhandle(i))
{
last = i + 1;
}
}
if (last)
{
StartupInfo.cbReserved2 = sizeof(ULONG) + last * (sizeof(char) + sizeof(HANDLE));
StartupInfo.lpReserved2 = malloc(StartupInfo.cbReserved2);
if (StartupInfo.lpReserved2 == NULL)
{
errno = ENOMEM;
return -1;
}
*(DWORD*)StartupInfo.lpReserved2 = last;
fmode = (char*)(StartupInfo.lpReserved2 + sizeof(ULONG));
hFile = (HANDLE*)(StartupInfo.lpReserved2 + sizeof(ULONG) + last * sizeof(char));
for (i = 0; i < last; i++)
{
int _mode = __fileno_getmode(i);
HANDLE h = _get_osfhandle(i);
/* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3)
* is possible wrong
*/
if ((((ULONG)h) & 0x10000003) == 0x3 || _mode & _O_NOINHERIT || (i < 3 && mode == _P_DETACH))
{
*hFile = INVALID_HANDLE_VALUE;
*fmode = 0;
}
else
{
DWORD dwFlags;
BOOL bFlag;
bFlag = GetHandleInformation(h, &dwFlags);
if (bFlag && (dwFlags & HANDLE_FLAG_INHERIT))
{
*hFile = h;
*fmode = (_O_ACCMODE & _mode) | (((_O_TEXT | _O_BINARY) & _mode) >> 8);
}
else
{
*hFile = INVALID_HANDLE_VALUE;
*fmode = 0;
}
fmode++;
hFile++;
}
}
}
bResult = CreateProcessA((char *)cmdname,
(char *)args,
NULL,
NULL,
TRUE,
mode == _P_DETACH ? DETACHED_PROCESS : 0,
(LPVOID)envp,
NULL,
&StartupInfo,
&ProcessInformation);
if (StartupInfo.lpReserved2)
{
free(StartupInfo.lpReserved2);
}
if (!bResult)
{
dwError = GetLastError();
DPRINT("%x\n", dwError);
__set_errno(dwError);
return -1;
}
CloseHandle(ProcessInformation.hThread);
switch(mode)
{
case _P_OVERLAY:
_exit(0);
case _P_WAIT:
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode);
CloseHandle(ProcessInformation.hProcess);
return (int)dwExitCode;
case _P_DETACH:
CloseHandle(ProcessInformation.hProcess);
return 0;
}
return (int)ProcessInformation.hProcess;
}
int _spawnl(int mode, const char *cmdname, const char* arg0, ...)
{
va_list argp;
char* args;
int ret = -1;
DPRINT("_spawnl('%s')\n", cmdname);
va_start(argp, arg0);
args = valisttos(arg0, argp, ' ');
if (args)
{
ret = do_spawn(mode, cmdname, args, NULL);
free(args);
}
return ret;
}
int _spawnv(int mode, const char *cmdname, char* const* argv)
{
char* args;
int ret = -1;
DPRINT("_spawnv('%s')\n", cmdname);
args = argvtos(argv, ' ');
if (args)
{
ret = do_spawn(mode, cmdname, args, NULL);
free(args);
}
return ret;
}
int _spawnle(int mode, const char *cmdname, const char* arg0, ... /*, NULL, const char* const* envp*/)
{
va_list argp;
char* args;
char* envs;
char* const* ptr;
int ret = -1;
DPRINT("_spawnle('%s')\n", cmdname);
va_start(argp, arg0);
args = valisttos(arg0, argp, ' ');
do
{
ptr = (char* const*)va_arg(argp, char*);
}
while (ptr != NULL);
envs = argvtos(ptr, 0);
if (args)
{
ret = do_spawn(mode, cmdname, args, envs);
free(args);
}
if (envs)
{
free(envs);
}
return ret;
}
int _spawnve(int mode, const char *cmdname, char* const* argv, char* const* envp)
{
char *args;
char *envs;
int ret = -1;
DPRINT("_spawnve('%s')\n", cmdname);
args = argvtos(argv, ' ');
envs = argvtos(envp, 0);
if (args)
{
ret = do_spawn(mode, cmdname, args, envs);
free(args);
}
if (envs)
{
free(envs);
}
return ret;
}
int _spawnvp(int mode, const char* cmdname, char* const* argv)
{
char pathname[FILENAME_MAX];
DPRINT("_spawnvp('%s')\n", cmdname);
_searchenv(cmdname, "PATH", pathname);
return _spawnv(mode, pathname[0] ? pathname : cmdname, argv);
}
int _spawnlpe(int mode, const char* cmdname, const char* arg0, .../*, NULL, const char* const* envp*/)
{
va_list argp;
char* args;
char* envs;
char* const * ptr;
int ret = -1;
char pathname[FILENAME_MAX];
DPRINT("_spawnlpe('%s')\n", cmdname);
_searchenv(cmdname, "PATH", pathname);
va_start(argp, arg0);
args = valisttos(arg0, argp, ' ');
do
{
ptr = (char* const*)va_arg(argp, char*);
}
while (ptr != NULL);
envs = argvtos(ptr, 0);
if (args)
{
ret = do_spawn(mode, pathname[0] ? pathname : cmdname, args, envs);
free(args);
}
if (envs)
{
free(envs);
}
return ret;
}
int _spawnvpe(int mode, const char* cmdname, char* const* argv, char* const* envp)
{
char pathname[FILENAME_MAX];
DPRINT("_spawnvpe('%s')\n", cmdname);
_searchenv(cmdname, "PATH", pathname);
return _spawnve(mode, pathname[0] ? pathname : cmdname, argv, envp);
}
int _execl(const char* cmdname, const char* arg0, ...)
{
char* args;
va_list argp;
int ret = -1;
DPRINT("_execl('%s')\n", cmdname);
va_start(argp, arg0);
args = valisttos(arg0, argp, ' ');
if (args)
{
ret = do_spawn(P_OVERLAY, cmdname, args, NULL);
free(args);
}
return ret;
}
int _execv(const char* cmdname, char* const* argv)
{
DPRINT("_execv('%s')\n", cmdname);
return _spawnv(P_OVERLAY, cmdname, argv);
}
int _execle(const char* cmdname, const char* arg0, ... /*, NULL, char* const* envp */)
{
va_list argp;
char* args;
char* envs;
char* const* ptr;
int ret = -1;
DPRINT("_execle('%s')\n", cmdname);
va_start(argp, arg0);
args = valisttos(arg0, argp, ' ');
do
{
ptr = (char* const*)va_arg(argp, char*);
}
while (ptr != NULL);
envs = argvtos((char**)ptr, 0);
if (args)
{
ret = do_spawn(P_OVERLAY, cmdname, args, envs);
free(args);
}
if (envs)
{
free(envs);
}
return ret;
}
int _execve(const char* cmdname, char* const* argv, char* const* envp)
{
DPRINT("_execve('%s')\n", cmdname);
return _spawnve(P_OVERLAY, cmdname, argv, envp);
}
int _execlp(const char* cmdname, const char* arg0, ...)
{
char* args;
va_list argp;
int ret = -1;
char pathname[FILENAME_MAX];
DPRINT("_execlp('%s')\n", cmdname);
_searchenv(cmdname, "PATH", pathname);
va_start(argp, arg0);
args = valisttos(arg0, argp, ' ');
if (args)
{
ret = do_spawn(P_OVERLAY, pathname[0] ? pathname : cmdname, args, NULL);
free(args);
}
return ret;
}
int _execvp(const char* cmdname, char* const* argv)
{
DPRINT("_execvp('%s')\n", cmdname);
return _spawnvp(P_OVERLAY, cmdname, argv);
}
int _execlpe(const char* cmdname, const char* arg0, ... /*, NULL, char* const* envp */)
{
va_list argp;
char* args;
char* envs;
char* const* ptr;
int ret = -1;
char pathname[FILENAME_MAX];
DPRINT("_execlpe('%s')\n", cmdname);
_searchenv(cmdname, "PATH", pathname);
va_start(argp, arg0);
args = valisttos(arg0, argp, ' ');
do
{
ptr = (char* const*)va_arg(argp, char*);
}
while (ptr != NULL);
envs = argvtos(ptr, 0);
if (args)
{
ret = do_spawn(P_OVERLAY, pathname[0] ? pathname : cmdname, args, envs);
free(args);
}
if (envs)
{
free(envs);
}
return ret;
}
int _execvpe(const char* cmdname, char* const* argv, char* const* envp)
{
DPRINT("_execvpe('%s')\n", cmdname);
return _spawnvpe(P_OVERLAY, cmdname, argv, envp);
}