From 9b875ab82cc266d41b85beefe7d1234f133928ff Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Thu, 31 Oct 2002 07:26:08 +0000 Subject: [PATCH] Merged all exec* and spawn* functions in one source file. Reduced some overhead. svn path=/trunk/; revision=3682 --- reactos/lib/msvcrt/Makefile | 19 +- reactos/lib/msvcrt/process/process.c | 478 +++++++++++++++++++++++++++ 2 files changed, 480 insertions(+), 17 deletions(-) create mode 100644 reactos/lib/msvcrt/process/process.c diff --git a/reactos/lib/msvcrt/Makefile b/reactos/lib/msvcrt/Makefile index 51c1c7221d0..82f23fdda00 100644 --- a/reactos/lib/msvcrt/Makefile +++ b/reactos/lib/msvcrt/Makefile @@ -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 diff --git a/reactos/lib/msvcrt/process/process.c b/reactos/lib/msvcrt/process/process.c new file mode 100644 index 00000000000..15725da9e00 --- /dev/null +++ b/reactos/lib/msvcrt/process/process.c @@ -0,0 +1,478 @@ +/* $Id: process.c,v 1.1 2002/10/31 07:26:08 hbirr Exp $ */ +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +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); +}