summaryrefslogtreecommitdiffstats
path: root/private/crt32/exec
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/crt32/exec
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/crt32/exec')
-rw-r--r--private/crt32/exec/cenvarg.c373
-rw-r--r--private/crt32/exec/cfinfo.c22
-rw-r--r--private/crt32/exec/dospawn.c303
-rw-r--r--private/crt32/exec/execl.c76
-rw-r--r--private/crt32/exec/execle.c79
-rw-r--r--private/crt32/exec/execlp.c77
-rw-r--r--private/crt32/exec/execlpe.c82
-rw-r--r--private/crt32/exec/execv.c60
-rw-r--r--private/crt32/exec/execve.c2
-rw-r--r--private/crt32/exec/execvp.c62
-rw-r--r--private/crt32/exec/execvpe.c171
-rw-r--r--private/crt32/exec/fileinfo.c22
-rw-r--r--private/crt32/exec/getproc.c62
-rw-r--r--private/crt32/exec/loaddll.c70
-rw-r--r--private/crt32/exec/makefile6
-rw-r--r--private/crt32/exec/sources58
-rw-r--r--private/crt32/exec/spawnl.c83
-rw-r--r--private/crt32/exec/spawnle.c83
-rw-r--r--private/crt32/exec/spawnlp.c85
-rw-r--r--private/crt32/exec/spawnlpe.c87
-rw-r--r--private/crt32/exec/spawnv.c67
-rw-r--r--private/crt32/exec/spawnve.c318
-rw-r--r--private/crt32/exec/spawnvp.c62
-rw-r--r--private/crt32/exec/spawnvpe.c209
-rw-r--r--private/crt32/exec/system.c95
-rw-r--r--private/crt32/exec/wait.c199
26 files changed, 2813 insertions, 0 deletions
diff --git a/private/crt32/exec/cenvarg.c b/private/crt32/exec/cenvarg.c
new file mode 100644
index 000000000..0a0755748
--- /dev/null
+++ b/private/crt32/exec/cenvarg.c
@@ -0,0 +1,373 @@
+/***
+*cenvarg.c - OS/2 set up environment, command line blocks
+*
+* Copyright (c) 1986-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _cenvarg() - setup environment/command line blocks
+*
+*Revision History:
+* 05-20-86 SKS Module created
+* 10-03-86 SKS Wasn't clearing final null byte in environment block
+* 10-13-86 SKS Check for environment segment > 32 KB (esp. > 64 KB)
+* 10-23-86 SKS New format for C_FILE_INFO for Prot-Mode execution
+* 12-17-86 SKS Support for new command line format
+* 01-21-87 BCM Removed DCR475 switch, new command line format official
+* 07-07-87 JCR Corrected bug in ENV_MAX check
+* 05-24-88 SJM Removed support for ;C_FILE_INFO for Real-Mode execution
+* 06-01-88 SJM Added support for .cmd files via comname/cmdname
+* 12-27-88 JCR Added support for _fileinfo option
+* 03-08-90 GJF Made calling type _CALLTYPE1, added #include
+* <cruntime.h>, removed #include <register.h> and fixed
+* the copyright. Also, cleaned up the formatting a bit.
+* 04-02-90 GJF Added const to arg types.
+* 08-10-90 SBM Compiles cleanly with -W3
+* 09-27-90 GJF New-style function declarator.
+* 12-06-90 GJF Added Win32 support. That is, support for encoding
+* _osfinfo[] data into _C_FILE_INFO environment variable.
+* 01-18-91 GJF ANSI naming.
+* 02-05-91 SRW Removed usage of _C_FILE_INFO to pass binary data
+* to child process. [_WIN32_]
+* 05-07-92 SKS Remove code which stripped the extension from a batch
+* file while building arguments to CMD.EXE. This was
+* done long ago (1988) for DOS 3.X, I think.
+* 10-24-92 SKS Remove special code for batch files - not needed on NT
+* 07-15-93 SRW Added _capture_argv function
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <stdio.h>
+#include <errno.h>
+#include <msdos.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <internal.h>
+#include <string.h>
+
+#define ENV_MAX 32767
+
+/***
+*int _cenvarg(argv, envp, argblk, envblk, name) - set up cmd line/environ
+*
+*Purpose:
+* Set up the block forms of the environment and the command line.
+* If "envp" is null, "_environ" is used instead.
+* File handle info is passed in the environment if _fileinfo is !0.
+*
+*Entry:
+* char **argv - argument vector
+* char **envp - environment vector
+* char **argblk - pointer to pointer set to malloc'ed space for args
+* char **envblk - pointer to pointer set to malloc'ed space for env
+* char *name - name of program being invoked
+*
+*Exit:
+* returns 0 if ok, -1 if fails
+* stores through argblk and envblk
+* (calls malloc)
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _cenvarg (
+ const char * const *argv,
+ const char * const *envp,
+ char **argblk,
+ char **envblk,
+ const char *name
+ )
+{
+ REG1 const char * const *vp;
+ REG2 unsigned tmp;
+ REG3 char *cptr;
+ unsigned arg_len;
+ int cfi_len; /* counts the number of file handles in CFI */
+
+ /*
+ * Null environment pointer "envp" means use global variable "_environ"
+ */
+
+#ifdef _CRUISER_
+ int i; /* loop counter */
+
+ if (!envp)
+ envp = _environ;
+#endif /* _CRUISER_ */
+
+ /*
+ * Allocate space for command line string
+ * tmp counts the number of bytes in the command line string
+ * including spaces between arguments
+ * An empty string is special -- 2 bytes
+ */
+
+ for (vp = argv, tmp = 2; *vp; tmp += strlen(*vp++) + 1)
+ if( tmp > ENV_MAX )
+ break;
+
+ /*
+ * Make sure there are not already > 32 KB in strings
+ */
+
+ if ((arg_len = tmp) >= ENV_MAX) {
+ *envblk = NULL;
+ errno = E2BIG;
+ _doserrno = E_badenv;
+ return(-1);
+ }
+
+ /*
+ * Allocate space for the command line plus 2 null bytes
+ */
+
+ if ( (*argblk = malloc(tmp)) == NULL) {
+ *envblk = NULL;
+ errno = ENOMEM;
+ _doserrno = E_nomem;
+ return(-1);
+ }
+
+ /*
+ * Allocate space for environment strings
+ * tmp counts the number of bytes in the environment strings
+ * including nulls between strings
+ * Also add "_C_FILE_INFO=" string
+ */
+
+#ifdef _WIN32_
+ if (envp)
+#endif /* _WIN32_ */
+
+ for (vp = envp, tmp = 2; *vp; tmp += strlen(*vp++) + 1)
+ if( tmp > ENV_MAX )
+ break;
+
+#ifdef _CRUISER_
+ if (_fileinfo)
+ for (cfi_len = _nfile; cfi_len && !_osfile[cfi_len-1];
+ cfi_len--) ;
+ else
+ cfi_len = 0; /* no _C_FILE_INFO */
+
+ /*
+ * mode-independent C-FILE-INFO calculation
+ */
+
+ if (cfi_len) /* Add 1 (each) for the "=" & null byte */
+ /* Plus 2 bytes for each value in _osfile */
+ tmp += /* strlen(_acfinfo) */ CFI_LENGTH + 2 + cfi_len +
+ cfi_len;
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ /*
+ ** The _osfile and _osfhnd arrays are passed as binary data in
+ ** dospawn.c
+ */
+
+ cfi_len = 0; /* no _C_FILE_INFO */
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+#ifdef _WIN32_
+ if (!envp)
+ *envblk = NULL;
+ else {
+#endif /* _WIN32_ */
+
+ /*
+ * Check for too many strings to be placed in the environment
+ * Increment tmp for final null byte after environment strings
+ * "tmp + arg_len + strlen(name) + 1" must also be < ENV_MAX
+ * Do (long) comparison in case tmp > ENV_MAX from C_FILE_INFO
+ */
+
+ if( (long) tmp + arg_len + strlen(name) > ENV_MAX - 1 ) {
+ free(*argblk);
+ *argblk = NULL;
+ errno = E2BIG;
+ _doserrno = E_badenv;
+ return(-1);
+ }
+
+ /*
+ * Allocate space for the environment strings plus extra null byte
+ */
+
+ if( !(*envblk = malloc(tmp)) ) {
+ free(*argblk);
+ *argblk = NULL;
+ errno = ENOMEM;
+ _doserrno = E_nomem;
+ return(-1);
+ }
+
+#ifdef _WIN32_
+ }
+#endif /* _WIN32_ */
+
+ /*
+ * Build the command line by concatenating the argument strings
+ * with spaces between, and two null bytes at the end
+ * NOTE: The argv[0] argument is followed by a null.
+ */
+
+ cptr = *argblk;
+ vp = argv;
+
+ if (!*vp) /* Empty argument list ? */
+ ++cptr; /* just two null bytes */
+ else { /* argv[0] must be followed by a null */
+ strcpy(cptr, *vp);
+ cptr += strlen(*vp++) + 1;
+ }
+
+ while( *vp ) {
+ strcpy(cptr, *vp);
+ cptr += strlen(*vp++);
+ *cptr++ = ' ';
+ }
+
+ * cptr = cptr[ -1 ] = '\0'; /* remove extra blank, add double null */
+
+#ifdef _WIN32_
+ if (envp) {
+#endif /* _WIN32_ */
+
+ /*
+ * Build the environment block by concatenating the environment strings
+ * with nulls between and two null bytes at the end
+ * C_FILE_INFO is stored as if it were an environment string
+ */
+
+ cptr = *envblk;
+ vp = envp;
+
+ if( !(*vp || cfi_len) ) /* No environment strings? */
+ *cptr++ = '\0'; /* just two null bytes */
+
+ while( *vp ) {
+ strcpy(cptr, *vp);
+ cptr += 1 + strlen(*vp++);
+ }
+
+#ifdef _CRUISER_
+
+ if(cfi_len) {
+ strcpy(cptr,_acfinfo);
+ cptr += /* strlen(_acfinfo) */ CFI_LENGTH;
+
+ i = cfi_len;
+ for(tmp = 0; i--; ++tmp) {
+ *cptr++ = (char)(((_osfile[tmp] >> 4) & 0xF) + 'A');
+ *cptr++ = (char)((_osfile[tmp] & 0xF) + 'A');
+ }
+ *cptr++ = '\0';
+ }
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ /*
+ ** The _osfile and _osfhnd arrays are passed as binary data in
+ ** dospawn.c
+ */
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+#ifdef _WIN32_
+ }
+#endif /* _WIN32_ */
+
+ /*
+ * Extra null terminates the segment
+ */
+ *cptr = '\0';
+
+ return(0);
+}
+
+
+/***
+*int _capture_argv(arglist, static_argv, max_static_entries) - set up argv array
+* for exec?? functions
+*
+*Purpose:
+* Set up the argv array for the exec?? functions by captures the arguments
+* from the passed va_list into the static_argv array. If the size of the
+* static_argv array as specified by the max_static_entries parameter is
+* not large enough, then allocates a dynamic array to hold the arguments.
+* Return the address of the final argv array. If NULL then not enough
+* memory to hold argument array. If different from static_argv parameter
+* then call must free the return argv array when done with it.
+*
+* The scan of the arglist is terminated when a NULL argument is reached.
+* The terminating NULL parameter is stored in the resulting argv array.
+*
+*Entry:
+* va_list *arglist - pointer to variable length argument list.
+* char *firstarg - first argument to store in array
+* char **static_argv - pointer to static argv to use.
+* size_t max_static_entries - maximum number of entries that can be placed
+* in static_argv array.
+*
+*Exit:
+* returns NULL if no memory.
+* Otherwise returns pointer to argv array.
+* (sometimes calls malloc)
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+char ** _CALLTYPE1 _capture_argv(
+ va_list *arglist,
+ const char *firstarg,
+ char **static_argv,
+ size_t max_static_entries
+ )
+{
+ char ** argv;
+ char * nextarg;
+ size_t i;
+ size_t max_entries;
+
+ nextarg = (char *)firstarg;
+ argv = static_argv;
+ max_entries = max_static_entries;
+ i = 0;
+ for (;;) {
+ if (i >= max_entries) {
+ if (argv == static_argv)
+ argv = malloc((max_entries * 2) * sizeof(char *));
+ else
+ argv = realloc(argv, (max_entries * 2) * sizeof(char *));
+
+ if (argv == NULL) break;
+ max_entries += max_entries;
+ }
+
+ argv[ i++ ] = nextarg;
+ if (nextarg == NULL) break;
+ nextarg = va_arg(*arglist, char *);
+ }
+
+ return argv;
+}
diff --git a/private/crt32/exec/cfinfo.c b/private/crt32/exec/cfinfo.c
new file mode 100644
index 000000000..e761a1f68
--- /dev/null
+++ b/private/crt32/exec/cfinfo.c
@@ -0,0 +1,22 @@
+/***
+*cfinfo.c - clears C file info flag
+*
+* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* Clears the C file info flag. By default, the openfile information
+* is NOT passed along to children on spawn/exec calls. If the flag
+* is set, openfile information WILL get passed on to children on
+* spawn/exec calls.
+*
+*Revision History:
+* 06-07-89 PHG Module created, based on asm version
+* 04-03-90 GJF Added #include <cruntime.h>. Also, fixed the copyright.
+* 01-23-92 GJF Added #include <stdlib.h> (contains decl of _fileinfo).
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <stdlib.h>
+
+int _fileinfo = 0;
diff --git a/private/crt32/exec/dospawn.c b/private/crt32/exec/dospawn.c
new file mode 100644
index 000000000..900c2996d
--- /dev/null
+++ b/private/crt32/exec/dospawn.c
@@ -0,0 +1,303 @@
+/***
+*dospawn.c - OS/2 spawn a child process
+*
+* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _dospawn - spawn a child process
+*
+*Revision History:
+* 06-07-89 PHG Module created, based on asm version
+* 03-08-90 GJF Made calling type _CALLTYPE2 (for now), added #include
+* <cruntime.h> and fixed the copyright. Also, cleaned
+* up the formatting a bit.
+* 04-02-90 GJF Now _CALLTYPE1. Added const to type of name arg.
+* 07-24-90 SBM Removed '32' from API names
+* 09-27-90 GJF New-style function declarator.
+* 10-30-90 GJF Added _p_overlay (temporary hack).
+* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
+* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
+* 01-16-91 SRW Fixed return value for dospawn [_WIN32_]
+* 01-17-91 GJF ANSI naming.
+* 01-25-91 SRW Changed CreateProcess parameters [_WIN32_]
+* 01-29-91 SRW Changed CreateProcess parameters again [_WIN32_]
+* 02-05-91 SRW Changed to pass _osfile and _osfhnd arrays as binary
+* data to child process. [_WIN32_]
+* 02-18-91 SRW Fixed code to return correct process handle and close
+* handle for P_WAIT case. [_WIN32_]
+* 04-05-91 SRW Fixed code to free StartupInfo.lpReserved2 after
+* CreateProcess call. [_WIN32_]
+* 04-26-91 SRW Removed level 3 warnings (_WIN32_)
+* 12-02-91 SRW Fixed command line setup code to not append an extra
+* space [_WIN32_]
+* 12-16-91 GJF Return full 32-bit exit code from the child process
+* [_WIN32_].
+* 02-14-92 GJF Replaced _nfile with _nhandle for Win32.
+* 02-18-92 GJF Merged in 12-16-91 change from \\vangogh version
+* 11-20-92 SKS errno/_doserrno must be 0 in case of success. This
+* will distinguish a child process return code of -1L
+* (errno == 0) from an actual error (where errno != 0).
+* 01-08-93 CFW Added code to handle _P_DETACH case; add fdwCreate variable,
+* nuke stdin, stdout, stderr entries of _osfile & _osfhnd tables,
+* close process handle to completely detach process
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <internal.h>
+#include <process.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+int _VARTYPE1 _p_overlay = 2;
+
+/***
+*int _dospawn(mode, name, cmdblk, envblk) - spawn a child process
+*
+*Purpose:
+* Spawns a child process
+*
+*Entry:
+* int mode - _P_WAIT, _P_NOWAIT, _P_NOWAITO, _P_OVERLAY, or _P_DETACH
+* char *name - name of program to execute
+* char *cmdblk - parameter block
+* char *envblk - environment block
+*
+*Exit:
+* _P_OVERLAY: -1 = error, otherwise doesn't return
+* _P_WAIT: termination code << 8 + result code
+* _P_DETACH: -1 = error, 0 = success
+* others: PID of process
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _dospawn (
+ int mode,
+ const char *name,
+ char *cmdblk,
+ char *envblk
+ )
+{
+ char syncexec, asyncresult, background;
+#ifdef _CRUISER_
+
+ RESULTCODES result_codes; /* result code of DosExecPgm */
+ ULONG exec_flags; /* flags for DosExecPgm */
+ ULONG dosretval; /* OS/2 return value */
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ LPSTR CommandLine;
+ STARTUPINFO StartupInfo;
+ PROCESS_INFORMATION ProcessInformation;
+ BOOL CreateProcessStatus;
+ ULONG dosretval; /* OS return value */
+ DWORD retval;
+ DWORD fdwCreate = 0; /* Flags for CreateProcess */
+ int cfi_len; /* counts the number of file handles in CFI */
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ /* translate input mode value to individual flags */
+ syncexec = asyncresult = background = 0;
+ switch (mode) {
+ case _P_WAIT: syncexec=1; break; /* synchronous execution */
+ case 2: /* _P_OVERLAY */
+ case _P_NOWAITO: break; /* asynchronous execution */
+ case _P_NOWAIT: asyncresult=1; break; /* asynch + remember result */
+ case _P_DETACH: background=1; break; /* detached in null scrn grp */
+ default:
+ /* invalid mode */
+ errno = EINVAL;
+ _doserrno = 0; /* not a Dos error */
+ return -1;
+ }
+
+#ifdef _CRUISER_
+ /* translate input mode value to system call value */
+ if (syncexec)
+ exec_flags = EXEC_SYNC;
+ else
+ if (asyncresult)
+ exec_flags = EXEC_ASYNCRESULT;
+ else
+ if (background)
+ exec_flags = EXEC_BACKGROUND;
+ else
+ exec_flags = EXEC_ASYNC;
+
+ /* issue system call to run process, want no DynaLink failure name */
+ if (dosretval = DOSEXECPGM(NULL, 0, exec_flags, cmdblk, envblk,
+ &result_codes, (char *)name)) {
+ /* error -- map error code and return */
+ _dosmaperr(dosretval);
+ return -1;
+ }
+
+ if (mode == 2 /* _P_OVERLAY */) {
+ /* destroy ourselves */
+ _exit(0);
+ }
+ else if (mode == _P_WAIT) {
+ /* return termination code and exit code -- note we only
+ return low byte of result code, although OS/2 allows a
+ word -- this is for XENIX compatability */
+ return ((result_codes.codeTerminate & 0xFF) << 8) +
+ (result_codes.codeResult & 0xFF);
+ }
+ else {
+ /* asynchronous spawn -- return PID */
+ return result_codes.codeTerminate;
+ }
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+ //
+ // Loop over null separate arguments, and replace null separators
+ // with spaces to turn it back into a single null terminated
+ // command line.
+ //
+ CommandLine = cmdblk;
+ while (*cmdblk) {
+ while (*cmdblk) {
+ cmdblk++;
+ }
+
+ //
+ // If not last argument, turn null separator into a space.
+ //
+ if (cmdblk[1] != '\0') {
+ *cmdblk++ = ' ';
+ }
+ }
+
+ memset(&StartupInfo,0,sizeof(StartupInfo));
+ StartupInfo.cb = sizeof(StartupInfo);
+
+ for (cfi_len = _nhandle; cfi_len && !_osfile[cfi_len-1];cfi_len--) {
+ }
+
+ StartupInfo.cbReserved2 = (WORD)(sizeof( int ) +
+ (cfi_len *
+ (sizeof( char ) + sizeof( long ) )
+ )
+ );
+ StartupInfo.lpReserved2 = calloc( StartupInfo.cbReserved2, 1 );
+ memcpy( StartupInfo.lpReserved2,
+ &cfi_len,
+ sizeof( int )
+ );
+ memcpy( StartupInfo.lpReserved2 + sizeof( int ),
+ _osfile,
+ cfi_len * sizeof( char )
+ );
+ memcpy( StartupInfo.lpReserved2 + sizeof( int ) +
+ (cfi_len * sizeof( char )),
+ _osfhnd,
+ cfi_len * sizeof( long )
+ );
+
+ if (background)
+ {
+ int fh;
+
+ /* child process is detached, cannot access console, must nuke first
+ three entries (stdin, stdout, stderr) in _osfile & _osfhnd tables */
+
+ // set _osfile[]
+ for ( fh = 0 ; fh <= 2 ; ++fh )
+ {
+ *(char *)(StartupInfo.lpReserved2
+ + sizeof(int)
+ + fh * sizeof(char)) = 0;
+ }
+
+ // set _osfhnd[]
+ for ( fh = 0 ; fh <= 2 ; ++fh )
+ {
+ *(long *)(StartupInfo.lpReserved2
+ + sizeof(int)
+ + cfi_len * sizeof(char)
+ + fh * sizeof(long)) = (long)INVALID_HANDLE_VALUE;
+ }
+
+ fdwCreate |= DETACHED_PROCESS;
+ }
+
+ /**
+ * Set errno to 0 to distinguish a child process
+ * which returns -1L from an error in the spawning
+ * (which will set errno to something non-zero
+ **/
+
+ _doserrno = errno = 0 ;
+
+ CreateProcessStatus = CreateProcess( (LPSTR)name,
+ CommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ fdwCreate,
+ envblk,
+ NULL,
+ &StartupInfo,
+ &ProcessInformation
+ );
+
+ dosretval = GetLastError();
+ free( StartupInfo.lpReserved2 );
+
+ if (!CreateProcessStatus)
+ {
+ _dosmaperr(dosretval);
+ return -1;
+ }
+
+ if (mode == 2 /* _P_OVERLAY */) {
+ /* destroy ourselves */
+ _exit(0);
+ }
+ else if (mode == _P_WAIT) {
+ WaitForSingleObject(ProcessInformation.hProcess, (DWORD)(-1L));
+
+ /* return termination code and exit code -- note we return
+ the full exit code */
+ GetExitCodeProcess(ProcessInformation.hProcess, &retval);
+
+ CloseHandle(ProcessInformation.hProcess);
+ }
+ else if (mode == _P_DETACH) {
+ /* like totally detached asynchronous spawn, dude,
+ close process handle, return 0 for success */
+ CloseHandle(ProcessInformation.hProcess);
+ retval = (DWORD)0;
+ }
+ else {
+ /* asynchronous spawn -- return PID */
+ retval = (DWORD)ProcessInformation.hProcess;
+ }
+
+ CloseHandle(ProcessInformation.hThread);
+ return retval;
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+}
diff --git a/private/crt32/exec/execl.c b/private/crt32/exec/execl.c
new file mode 100644
index 000000000..3c2d5efd5
--- /dev/null
+++ b/private/crt32/exec/execl.c
@@ -0,0 +1,76 @@
+/***
+*execl.c - execute a file with a list of arguments
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _execl() - execute a file with a list of arguments
+*
+*Revision History:
+* 10-14-83 RN written
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, indents. Added const attribute to
+* types of filename and arglist. #include-d PROCESS.H
+* and added ellipsis to match prototype.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include
+* <cruntime.h> and removed #include <register.h>.
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 02-14-90 SRW Use NULL instead of _environ to get default.
+* 07-16-93 SRW ALPHA Merge
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <process.h>
+#include <stdarg.h>
+#include <internal.h>
+
+/***
+*int _execl(filename, arglist) - execute a file with arg list
+*
+*Purpose:
+* Transform the argument list so it is a vector, then pass its address
+* to execve. Use a pointer to the default environment vector.
+*
+*Entry:
+* char *filename - file to execute
+* char *arglist - list of arguments
+* call as _execl(path, arg0, arg1, ..., argn, NULL);
+*
+*Exit:
+* destroys the calling process, hopefully
+* returns -1 if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE2 _execl (
+ const char *filename,
+ const char *arglist,
+ ...
+ )
+{
+ va_list vargs;
+ char * argbuf[64];
+ char ** argv;
+ int result;
+
+ assert(filename != NULL);
+ assert(*filename != '\0');
+ assert(arglist != NULL);
+ assert(*arglist != '\0');
+
+ va_start(vargs, arglist);
+ argv = _capture_argv(&vargs, arglist, argbuf, 64);
+ va_end(vargs);
+
+ result = _execve(filename,argv,NULL);
+ if (argv && argv != argbuf) free(argv);
+ return result;
+}
diff --git a/private/crt32/exec/execle.c b/private/crt32/exec/execle.c
new file mode 100644
index 000000000..2b74e4d31
--- /dev/null
+++ b/private/crt32/exec/execle.c
@@ -0,0 +1,79 @@
+/***
+*execle.c - execute a file with arg list and environment
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _execle() - execute a file
+*
+*Revision History:
+* 10-14-83 RN written
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, indents. Added const attribute to
+* types of filename and arglist. #include-d PROCESS.H
+* and added ellipsis to match prototype.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include
+* <cruntime.h> and removed #include <register.h>
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 07-16-93 SRW ALPHA Merge
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <stddef.h>
+#include <process.h>
+#include <stdarg.h>
+#include <internal.h>
+#include <malloc.h>
+
+/***
+*int _execle(filename, arglist) - execute a file
+*
+*Purpose:
+* Execute the given file (overlays the calling process).
+* We must dig the environment vector out of the stack and pass it
+* and address of argument vector to execve.
+*
+*Entry:
+* char *filename - file to execute
+* char *arglist - argument list followed by environment
+* should be called like _execle(path, arg0, arg1, ..., argn, NULL, envp);
+*
+*Exit:
+* destroys calling process (hopefully)
+* if fails, returns -1.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE2 _execle (
+ const char *filename,
+ const char *arglist,
+ ...
+ )
+{
+ va_list vargs;
+ char * argbuf[64];
+ char ** argv;
+ char ** envp;
+ int result;
+
+ assert(filename != NULL);
+ assert(*filename != '\0');
+ assert(arglist != NULL);
+ assert(*arglist != '\0');
+
+ va_start(vargs, arglist);
+ argv = _capture_argv(&vargs, arglist, argbuf, 64);
+ envp = va_arg(vargs, char **);
+ va_end(vargs);
+
+ result = _execve(filename,argv,envp);
+ if (argv && argv != argbuf) free(argv);
+ return result;
+}
diff --git a/private/crt32/exec/execlp.c b/private/crt32/exec/execlp.c
new file mode 100644
index 000000000..4e622be61
--- /dev/null
+++ b/private/crt32/exec/execlp.c
@@ -0,0 +1,77 @@
+/***
+*execlp.c - execute a file (search along PATH)
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _execlp() - execute a file and search along PATH
+*
+*Revision History:
+* 10-17-83 RN written
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, indents. Added const attribute to
+* types of filename and arglist. #include-d PROCESS.H
+* and added ellipsis to match prototype.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include
+* <cruntime.h> and removed #include <register.h>.
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 07-16-93 SRW ALPHA Merge
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <stddef.h>
+#include <process.h>
+#include <stdarg.h>
+#include <internal.h>
+#include <malloc.h>
+
+/***
+*int _execlp(filename, arglist) - execute a file, search along PATH
+*
+*Purpose:
+* Execute the given file with the given arguments; search along PATH
+* for the file. We pass the arguments to execvp where several paths
+* will be tried until one works.
+*
+*Entry:
+* char *filename - file to execute
+* char *arglist - argument list
+* call as _execlp(path, arg0, arg1, ..., argn, NULL);
+*
+*Exit:
+* destroys calling process (hopefully)
+* returns -1 if fails.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE2 _execlp (
+ const char *filename,
+ const char *arglist,
+ ...
+ )
+{
+ va_list vargs;
+ char * argbuf[64];
+ char ** argv;
+ int result;
+
+ assert(filename != NULL);
+ assert(*filename != '\0');
+ assert(arglist != NULL);
+ assert(*arglist != '\0');
+
+ va_start(vargs, arglist);
+ argv = _capture_argv(&vargs, arglist, argbuf, 64);
+ va_end(vargs);
+
+ result = _execvp(filename,argbuf);
+ if (argv && argv != argbuf) free(argv);
+ return result;
+}
diff --git a/private/crt32/exec/execlpe.c b/private/crt32/exec/execlpe.c
new file mode 100644
index 000000000..991cf757a
--- /dev/null
+++ b/private/crt32/exec/execlpe.c
@@ -0,0 +1,82 @@
+/***
+*execlpe.c - execute a file with environ, search along path
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _execlpe() - execute a file with environ and search along PATH
+*
+*Revision History:
+* 10-17-83 RN written
+* ??-??-?? TC added execlpe
+* 06-18-86 JMB added environment pointer which was erroneously missing
+* 06-11-87 PHG removed unnecessary environment pointer (isn't this
+* fun!)
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, indents. Added const attribute to
+* types of filename and arglist. #include-d PROCESS.H
+* and added ellipsis to match prototype.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include
+* <cruntime.h> and removed #include <register.h>
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 07-16-93 SRW ALPHA Merge
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <process.h>
+#include <stdarg.h>
+#include <internal.h>
+
+/***
+*int _execlpe(filename, arglist) - execute a file with environ
+*
+*Purpose:
+* Executes the given file with the parameters and the environment
+* which is passed after the parameters. Searches along the PATH
+* for the file (done by execvp).
+*
+*Entry:
+* char *filename - file to execute
+* char *arglist - argument list (environment is at the end)
+* call as _execlpe(path, arg0, arg1, ..., argn, NULL, envp);
+*
+*Exit:
+* destroys the calling process (hopefully)
+* if fails, returns -1
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE2 _execlpe (
+ const char *filename,
+ const char *arglist,
+ ...
+ )
+{
+ va_list vargs;
+ char * argbuf[64];
+ char ** argv;
+ char ** envp;
+ int result;
+
+ assert(filename != NULL);
+ assert(*filename != '\0');
+ assert(arglist != NULL);
+ assert(*arglist != '\0');
+
+ va_start(vargs, arglist);
+ argv = _capture_argv(&vargs, arglist, argbuf, 64);
+ envp = va_arg(vargs, char **);
+ va_end(vargs);
+
+ result = _execvpe(filename,argv,envp);
+ if (argv && argv != argbuf) free(argv);
+ return result;
+}
diff --git a/private/crt32/exec/execv.c b/private/crt32/exec/execv.c
new file mode 100644
index 000000000..a369e3738
--- /dev/null
+++ b/private/crt32/exec/execv.c
@@ -0,0 +1,60 @@
+/***
+*execv.c - execute a file
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _execv() - execute a file
+*
+*Revision History:
+* 10-14-83 RN written
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, indents. Added const attribute to
+* types of filename and argvector.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h> and removed #include <register.h>
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 02-14-90 SRW Use NULL instead of _environ to get default.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <process.h>
+
+/***
+*int _execv(filename, argvector) - execute a file
+*
+*Purpose:
+* Executes a file with given arguments. Passes arguments to _execve and
+* uses pointer to the default environment.
+*
+*Entry:
+* char *filename - file to execute
+* char **argvector - vector of arguments.
+*
+*Exit:
+* destroys calling process (hopefully)
+* if fails, returns -1
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _execv (
+ const char *filename,
+ const char * const *argvector
+ )
+{
+ assert(filename != NULL);
+ assert(*filename != '\0');
+ assert(argvector != NULL);
+ assert(*argvector != NULL);
+ assert(**argvector != '\0');
+
+ return(_execve(filename,argvector,NULL));
+}
diff --git a/private/crt32/exec/execve.c b/private/crt32/exec/execve.c
new file mode 100644
index 000000000..386ed4d0f
--- /dev/null
+++ b/private/crt32/exec/execve.c
@@ -0,0 +1,2 @@
+#define EXECVE
+#include "spawnve.c"
diff --git a/private/crt32/exec/execvp.c b/private/crt32/exec/execvp.c
new file mode 100644
index 000000000..f6b94de8b
--- /dev/null
+++ b/private/crt32/exec/execvp.c
@@ -0,0 +1,62 @@
+/***
+*execvp.c - execute a file and search along PATH
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _execvp() - execute a file and search along PATH
+*
+*Revision History:
+* 10-17-83 RN written
+* 10-29-85 TC added execvpe capability
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, indents. Added const attribute to
+* types of filename and argvector.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h> and removed #include <register.h>
+* 05-21-90 GJF Fixed stack checking pragma syntax.
+* 08-24-90 SBM Removed check_stack pragma since workhorse execve
+* does stack checks
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 02-14-90 SRW Use NULL instead of _environ to get default.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <stdlib.h>
+#include <process.h>
+
+/***
+*int _execvp(filename, argvector) - execute file; search along PATH
+*
+*Purpose:
+* Execute the given file with given path and current environ.
+* try to execute the file. start with the name itself (directory '.'),
+* and if that doesn't work start prepending pathnames from the
+* environment until one works or we run out. if the file is a pathname,
+* don't go to the environment to get alternate paths. if errno comes
+* back ENOEXEC, try it as a shell command file with up to MAXARGS-2
+* arguments from the original vector. if a needed text file is busy,
+* wait a little while and try again before despairing completely
+* Actually calls _execvpe() to do all the work.
+*
+*Entry:
+* char *filename - file to execute
+* char **argvector - vector of arguments
+*
+*Exit:
+* destroys the calling process (hopefully)
+* if fails, returns -1
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _execvp (
+ REG3 const char *filename,
+ const char * const *argvector
+ )
+{
+ return _execvpe( filename, argvector, NULL );
+}
diff --git a/private/crt32/exec/execvpe.c b/private/crt32/exec/execvpe.c
new file mode 100644
index 000000000..650f34b2a
--- /dev/null
+++ b/private/crt32/exec/execvpe.c
@@ -0,0 +1,171 @@
+/***
+*execvpe.c - execute a file with given environ; search along PATH
+*
+* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _execvpe() - execute a file with given environ
+*
+*Revision History:
+* 10-17-83 RN written
+* 10-29-85 TC added execvpe capability
+* 11-19-86 SKS handle both kinds of slashes
+* 12-01-86 JMB added Kanji file name support under conditional KANJI
+* switches, corrected header info
+* removed bogus check for env = b after call to strncpy().
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 09-05-88 SKS Treat EACCES the same as ENOENT -- keep trying
+* 10-18-88 GJF Removed copy of PATH string to local array, changed
+* bbuf to be a malloc-ed buffer. Removed bogus limits
+* on the size of that PATH string.
+* 10-26-88 GJF Don't search PATH when relative pathname is given (per
+* Stevesa). Also, if the name built from PATH component
+* and filename is a UNC name, allow any error.
+* 11-20-89 GJF Fixed copyright. Added const attribute to types of
+* filename, argvector and envptr. Also, added "#include
+* <jstring.h>" under KANJI switch (same as 5-17-89 change
+* to CRT version).
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h> and removed #include <register.h>. Also,
+* cleaned up the formatting a bit.
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 11-30-92 KRS Port _MBCS code from 16-bit tree.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <process.h>
+#include <mbstring.h>
+
+#define SLASH "\\"
+#define SLASHCHAR '\\'
+#define XSLASHCHAR '/'
+#define DELIMITER ";"
+
+#ifdef _MBCS
+/* note, the macro below assumes p is to pointer to a single-byte character
+ * or the 1st byte of a double-byte character, in a string.
+ */
+#define ISPSLASH(p) ( ((p) == _mbschr((p), SLASHCHAR)) || ((p) == \
+_mbschr((p), XSLASHCHAR)) )
+#else
+#define ISSLASH(c) ( ((c) == SLASHCHAR) || ((c) == XSLASHCHAR) )
+#endif
+
+
+/***
+*int _execvpe(filename, argvector, envvector) - execute a file
+*
+*Purpose:
+* Executes a file with given arguments and environment.
+* try to execute the file. start with the name itself (directory '.'),
+* and if that doesn't work start prepending pathnames from the
+* environment until one works or we run out. if the file is a pathname,
+* don't go to the environment to get alternate paths. If a needed text
+* file is busy, wait a little while and try again before despairing
+* completely
+*
+*Entry:
+* char *filename - file to execute
+* char **argvector - vector of arguments
+* char **envvector - vector of environment variables
+*
+*Exit:
+* destroys the calling process (hopefully)
+* if fails, returns -1
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _execvpe (
+ REG3 const char *filename,
+ const char * const *argvector,
+ const char * const *envptr
+ )
+{
+ REG1 char *env;
+ char *bbuf = NULL;
+ REG2 char *buf;
+ char *pfin;
+
+ assert(filename != NULL);
+ assert(*filename != '\0');
+ assert(argvector != NULL);
+ assert(*argvector != NULL);
+ assert(**argvector != '\0');
+
+ _execve(filename,argvector,envptr);
+
+ /* In a SBCS build, _mbschr will map to strchr. */
+
+ if ( (errno != ENOENT)
+ || (_mbschr(filename, SLASHCHAR) != NULL)
+ || (_mbschr(filename, XSLASHCHAR) != NULL)
+ || *filename && *(filename+1) == ':'
+ || !(env=getenv("PATH")) )
+ goto reterror;
+
+ /* allocate a buffer to hold alternate pathnames for the executable
+ */
+ if ( (buf = bbuf = (char *)malloc(_MAX_PATH)) == NULL ) goto reterror;
+
+ do {
+ /* copy a component into bbuf[], taking care not to overflow it
+ */
+ /* UNDONE: make sure ';' isn't 2nd byte of DBCS char */
+ while ( (*env) && (*env != ';') && (buf < bbuf+_MAX_PATH-2) )
+ *buf++ = *env++;
+
+ *buf = '\0';
+ pfin = --buf;
+ buf = bbuf;
+
+#ifdef _MBCS
+ if (*pfin == SLASHCHAR) {
+ if (pfin != _mbsrchr(buf,SLASHCHAR))
+ /* *pfin is the second byte of a double-byte
+ * character
+ */
+ strcat( buf, SLASH );
+ }
+ else if (*pfin != XSLASHCHAR)
+ strcat(buf, SLASH);
+#else
+ if (*pfin != SLASHCHAR && *pfin != XSLASHCHAR)
+ strcat(buf, SLASH);
+#endif
+
+ /* check that the final path will be of legal size. if so,
+ * build it. otherwise, return to the caller (return value
+ * and errno rename set from initial call to _execve()).
+ */
+ if ( (strlen(buf) + strlen(filename)) < _MAX_PATH )
+ strcat(buf, filename);
+ else
+ break;
+
+ _execve(buf, argvector, envptr);
+
+ if ( (errno != ENOENT)
+#ifdef _MBCS
+ && (!ISPSLASH(buf) || !ISPSLASH(buf+1)) )
+#else
+ && (!ISSLASH(*buf) || !ISSLASH(*(buf+1))) )
+#endif
+ break;
+ } while ( *env && env++ );
+
+reterror:
+ if (bbuf != NULL)
+ free(bbuf);
+
+ return(-1);
+}
diff --git a/private/crt32/exec/fileinfo.c b/private/crt32/exec/fileinfo.c
new file mode 100644
index 000000000..c617cf8c4
--- /dev/null
+++ b/private/crt32/exec/fileinfo.c
@@ -0,0 +1,22 @@
+/***
+*fileinfo.c - sets C file info flag
+*
+* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* Sets the C file info flag. By default, the openfile information
+* is NOT passed along to children on spawn/exec calls. If the flag
+* is set, openfile information WILL get passed on to children on
+* spawn/exec calls.
+*
+*Revision History:
+* 06-07-89 PHG Module created, based on asm version
+* 04-03-90 GJF Added #include <cruntime.h>. Also, fixed the copyright.
+* 01-23-92 GJF Added #include <stdlib.h> (contains decl of _fileinfo).
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <stdlib.h>
+
+int _fileinfo = -1;
diff --git a/private/crt32/exec/getproc.c b/private/crt32/exec/getproc.c
new file mode 100644
index 000000000..2cb78323e
--- /dev/null
+++ b/private/crt32/exec/getproc.c
@@ -0,0 +1,62 @@
+/***
+*getproc.c - Get the address of a procedure in a DLL.
+*
+* Copyright (c) 1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _getdllprocadd() - gets a procedure address by name or
+* ordinal
+*
+*Revision History:
+* 08-21-91 BWM Wrote module.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <process.h>
+
+#if !defined(_WIN32_)
+#error ERROR - ONLY WIN32 TARGET SUPPORTED!
+#endif
+
+/***
+*int (*)() _getdllprocaddr(handle, name, ordinal) - Get the address of a
+* DLL procedure specified by name or ordinal
+*
+*Purpose:
+*
+*Entry:
+* int handle - a DLL handle from _loaddll
+* char * name - Name of the procedure, or NULL to get by ordinal
+* int ordinal - Ordinal of the procedure, or -1 to get by name
+*
+*
+*Exit:
+* returns a pointer to the procedure if found
+* returns NULL if not found
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int (_CALLTYPE1 * _CALLTYPE1 _getdllprocaddr(int hMod,
+ char * szProcName,
+ int iOrdinal))()
+{
+ typedef int (_CALLTYPE1 * PFN)();
+
+ if (szProcName == NULL) {
+ if (iOrdinal <= 65535) {
+ return ((PFN)GetProcAddress((HANDLE)hMod, (LPSTR)iOrdinal));
+ }
+ }
+ else {
+ if (iOrdinal == -1) {
+ return ((PFN)GetProcAddress((HANDLE)hMod, szProcName));
+ }
+ }
+
+ return (NULL);
+
+}
diff --git a/private/crt32/exec/loaddll.c b/private/crt32/exec/loaddll.c
new file mode 100644
index 000000000..a6f41b7e2
--- /dev/null
+++ b/private/crt32/exec/loaddll.c
@@ -0,0 +1,70 @@
+/***
+*loaddll.c - load or free a Dynamic Link Library
+*
+* Copyright (c) 1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _loaddll() and _unloaddll() - load and unload DLL
+*
+*Revision History:
+* 08-21-91 BWM Wrote module.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <process.h>
+
+#if !defined(_WIN32_)
+#error ERROR - ONLY WIN32 TARGET SUPPORTED!
+#endif
+
+/***
+*int _loaddll(filename) - Load a dll
+*
+*Purpose:
+* Load a DLL into memory
+*
+*Entry:
+* char *filename - file to load
+*
+*Exit:
+* returns a unique DLL (module) handle if succeeds
+* returns 0 if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _loaddll(char * szName)
+{
+ return ((int)LoadLibrary(szName));
+}
+
+/***
+*int _unloaddll(handle) - Unload a dll
+*
+*Purpose:
+* Unloads a DLL. The resources of the DLL will be freed if no other
+* processes are using it.
+*
+*Entry:
+* int handle - handle from _loaddll
+*
+*Exit:
+* returns 0 if succeeds
+* returns DOS error if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _unloaddll(int hMod)
+{
+ if (!FreeLibrary((HANDLE)hMod)) {
+ return ((int)GetLastError());
+ }
+ return (0);
+}
diff --git a/private/crt32/exec/makefile b/private/crt32/exec/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/crt32/exec/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/crt32/exec/sources b/private/crt32/exec/sources
new file mode 100644
index 000000000..ed4f1c187
--- /dev/null
+++ b/private/crt32/exec/sources
@@ -0,0 +1,58 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+ Steve Wood (stevewo) 12-Apr-1990
+ jeffrob 29-sep-1990, use crt32.def
+
+NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl
+
+!ENDIF
+
+MAJORCOMP=crt
+MINORCOMP=exec
+
+TARGETNAME=exec
+TARGETPATH=..\obj
+TARGETTYPE=LIBRARY
+386_STDCALL=0
+
+!INCLUDE ..\crt32.def
+
+SOURCES=cenvarg.c \
+ fileinfo.c \
+ dospawn.c \
+ execl.c \
+ execle.c \
+ execlp.c \
+ execlpe.c \
+ execv.c \
+ execve.c \
+ execvp.c \
+ execvpe.c \
+ getproc.c \
+ loaddll.c \
+ spawnl.c \
+ spawnle.c \
+ spawnlp.c \
+ spawnlpe.c \
+ spawnv.c \
+ spawnve.c \
+ spawnvp.c \
+ spawnvpe.c \
+ system.c \
+ wait.c
diff --git a/private/crt32/exec/spawnl.c b/private/crt32/exec/spawnl.c
new file mode 100644
index 000000000..826e5be46
--- /dev/null
+++ b/private/crt32/exec/spawnl.c
@@ -0,0 +1,83 @@
+/***
+*spawnl.c - spawn a child process
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _spawnl() - spawn a child process
+*
+*Revision History:
+* 04-15-84 DFW Re-do to correspond to similar exec call format
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types
+* for pathname and arglist. #include-d PROCESS.H and
+* added ellipsis to match prototype.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2 and added #include
+* <cruntime.h>.
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 02-14-90 SRW Use NULL instead of _environ to get default.
+* 07-16-93 SRW ALPHA Merge
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <process.h>
+#include <stdarg.h>
+#include <internal.h>
+#include <malloc.h>
+
+/***
+*int _spawnl(modeflag, pathname, arglist) - spawn a child process
+*
+*Purpose:
+* Spawns a child process.
+* formats the parameters and calls spawnve to do the actual work. The
+* new process will inherit the parent's environment. NOTE - at least
+* one argument must be present. This argument is always, by convention,
+* the name of the file being spawned.
+*
+*Entry:
+* int modeflag - defines which mode of spawn (WAIT, NOWAIT, or OVERLAY)
+* only WAIT and OVERLAY are currently implemented
+* char *pathname - file to be spawned
+* char *arglist - list of argument
+* call as _spawnl(modeflag, path, arg0, arg1, ..., argn, NULL);
+*
+*Exit:
+* returns exit code of child process
+* returns -1 if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE2 _spawnl (
+ int modeflag,
+ const char *pathname,
+ const char *arglist,
+ ...
+ )
+{
+ va_list vargs;
+ char * argbuf[64];
+ char ** argv;
+ int result;
+
+ assert(pathname != NULL);
+ assert(*pathname != '\0');
+ assert(arglist != NULL);
+ assert(*arglist != '\0');
+
+ va_start(vargs, arglist);
+ argv = _capture_argv(&vargs, arglist, argbuf, 64);
+ va_end(vargs);
+
+ result = _spawnve(modeflag,pathname,argv,NULL);
+ if (argv && argv != argbuf) free(argv);
+ return result;
+}
diff --git a/private/crt32/exec/spawnle.c b/private/crt32/exec/spawnle.c
new file mode 100644
index 000000000..5b09417f2
--- /dev/null
+++ b/private/crt32/exec/spawnle.c
@@ -0,0 +1,83 @@
+/***
+*spawnle.c - spawn a child process with given environment
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _spawnle() - spawn a child process with given environ
+*
+*Revision History:
+* 04-15-84 DFW written
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types
+* for pathname and arglist. #include-d PROCESS.H and
+* added ellipsis to match prototype
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include
+* <cruntime.h> and removed #include <register.h>
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 07-16-93 SRW ALPHA Merge
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <stddef.h>
+#include <process.h>
+#include <stdarg.h>
+#include <internal.h>
+#include <malloc.h>
+
+/***
+*int _spawnle(modeflag, pathname, arglist) - spawn a child process with env.
+*
+*Purpose:
+* Spawns a child process with given parameters and environment.
+* formats the parameters and calls _spawnve to do the actual work.
+* NOTE - at least one argument must be present. This argument is always,
+* by convention, the name of the file being spawned.
+*
+*Entry:
+* int modeflag - mode of spawn (WAIT, NOWAIT, OVERLAY)
+* only WAIT, and OVERLAY currently implemented
+* char *pathname - name of file to spawn
+* char *arglist - argument list, environment is at the end
+* call as _spawnle(modeflag, path, arg0, arg1, ..., argn, NULL, envp);
+*
+*Exit:
+* returns exit code of spawned process
+* if fails, return -1
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE2 _spawnle (
+ int modeflag,
+ const char *pathname,
+ const char *arglist,
+ ...
+ )
+{
+ va_list vargs;
+ char * argbuf[64];
+ char ** argv;
+ char ** envp;
+ int result;
+
+ assert(pathname != NULL);
+ assert(*pathname != '\0');
+ assert(arglist != NULL);
+ assert(*arglist != '\0');
+
+ va_start(vargs, arglist);
+ argv = _capture_argv(&vargs, arglist, argbuf, 64);
+ envp = va_arg(vargs, char **);
+ va_end(vargs);
+
+ result = _spawnve(modeflag,pathname,argv,envp);
+ if (argv && argv != argbuf) free(argv);
+ return result;
+}
diff --git a/private/crt32/exec/spawnlp.c b/private/crt32/exec/spawnlp.c
new file mode 100644
index 000000000..22516c929
--- /dev/null
+++ b/private/crt32/exec/spawnlp.c
@@ -0,0 +1,85 @@
+/***
+*spawnlp.c - spawn a file; search along PATH
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _spawnlp() - spawn a file with search along PATH
+*
+*Revision History:
+* 04-15-84 DFW written
+* 10-29-85 TC added spawnlpe
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types
+* for filename and arglist. #include-d PROCESS.H and
+* added ellipsis to match prototype.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2 and added #include
+* <cruntime.h>.
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 07-16-93 SRW ALPHA Merge
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <stddef.h>
+#include <process.h>
+#include <stdarg.h>
+#include <internal.h>
+#include <malloc.h>
+
+/***
+*_spawnlp(modeflag, filename, arglist) - spawn file and search along PATH
+*
+*Purpose:
+* Spawns a child process.
+* formats the parameters and calls _spawnvp to do the work of searching
+* the PATH environment variable and calling _spawnve. The NULL
+* environment pointer indicates that the new process will inherit the
+* parents process's environment. NOTE - at least one argument must be
+* present. This argument is always, by convention, the name of the file
+* being spawned.
+*
+*Entry:
+* int modeflag - mode of spawn (WAIT, NOWAIT, OVERLAY)
+* only WAIT, OVERLAY currently implemented
+* char *pathname - file to spawn
+* char *arglist - argument list
+* call as _spawnlp(modeflag, path, arg0, arg1, ..., argn, NULL);
+*
+*Exit:
+* returns exit code of child process
+* returns -1 if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE2 _spawnlp (
+ int modeflag,
+ const char *filename,
+ const char *arglist,
+ ...
+ )
+{
+ va_list vargs;
+ char * argbuf[64];
+ char ** argv;
+ int result;
+
+ assert(filename != NULL);
+ assert(*filename != '\0');
+ assert(arglist != NULL);
+ assert(*arglist != '\0');
+
+ va_start(vargs, arglist);
+ argv = _capture_argv(&vargs, arglist, argbuf, 64);
+ va_end(vargs);
+
+ result = _spawnvp(modeflag,filename,argv);
+ if (argv && argv != argbuf) free(argv);
+ return result;
+}
diff --git a/private/crt32/exec/spawnlpe.c b/private/crt32/exec/spawnlpe.c
new file mode 100644
index 000000000..10520aecb
--- /dev/null
+++ b/private/crt32/exec/spawnlpe.c
@@ -0,0 +1,87 @@
+/***
+*spawnlpe.c - spawn a child process with environ and search along PATH
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _spawnlpe() - spawn a child process with environ/PATH search
+*
+*Revision History:
+* 04-15-84 DFW written
+* 10-29-85 TC added spawnlpe
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types
+* for filename and arglist. #include-d PROCESS.H and
+* added ellipsis to match prototype.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE2, added #include
+* <cruntime.h> and removed #include <register.h>.
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 07-16-93 SRW ALPHA Merge
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <stddef.h>
+#include <process.h>
+#include <stdarg.h>
+#include <internal.h>
+#include <malloc.h>
+
+/***
+*int _spawnlpe(modeflag, filename, arglist) - spawn a child process
+*
+*Purpose:
+* Spawns a child process.
+* formats the parameters and calls _spawnvpe to do the work of searching
+* the PATH environment variable and calling _spawnve. The NULL
+* environment pointer indicates that the new process will inherit the
+* parents process's environment. NOTE - at least one argument must be
+* present. This argument is always, by convention, the name of the file
+* being spawned.
+*
+*Entry:
+* int modeflag - defines what mode of spawn (WAIT, NOWAIT, OVERLAY)
+* only WAIT and OVERLAY currently supported
+* char *pathname - file to spawn
+* char *arglist - list of arguments (environ at end)
+* call as _spawnlpe(modeflag, path, arg0, arg1, ..., argn, NULL, envp);
+*
+*Exit:
+* returns exit code of spawned process
+* returns -1 if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE2 _spawnlpe (
+ int modeflag,
+ const char *filename,
+ const char *arglist,
+ ...
+ )
+{
+ va_list vargs;
+ char * argbuf[64];
+ char ** argv;
+ char ** envp;
+ int result;
+
+ assert(filename != NULL);
+ assert(*filename != '\0');
+ assert(arglist != NULL);
+ assert(*arglist != '\0');
+
+ va_start(vargs, arglist);
+ argv = _capture_argv(&vargs, arglist, argbuf, 64);
+ envp = va_arg(vargs, char **);
+ va_end(vargs);
+
+ result = _spawnvpe(modeflag,filename,argv,envp);
+ if (argv && argv != argbuf) free(argv);
+ return result;
+}
diff --git a/private/crt32/exec/spawnv.c b/private/crt32/exec/spawnv.c
new file mode 100644
index 000000000..fe90c213f
--- /dev/null
+++ b/private/crt32/exec/spawnv.c
@@ -0,0 +1,67 @@
+/***
+*spawnv.c - spawn a child process
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _spawnv() - spawn a child process
+*
+*Revision History:
+* 04-15-84 DFW written
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types
+* for pathname and argv.
+* 03-08-90 GJF Replace _LOAD_DS with _CALLTYPE1 and added #include
+* <cruntime.h>.
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 02-14-90 SRW Use NULL instead of _environ to get default.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <process.h>
+
+/***
+*int _spawnv(modeflag, pathname, argv) - spawn a child process
+*
+*Purpose:
+* Spawns a child process.
+* formats the parameters and calls _spawnve to do the actual work. The
+* NULL environment pointer indicates that the new process will inherit
+* the parents process's environment. NOTE - at least one argument must
+* be present. This argument is always, by convention, the name of the
+* file being spawned.
+*
+*Entry:
+* int modeflag - mode to spawn (WAIT, NOWAIT, or OVERLAY)
+* only WAIT and OVERLAY currently implemented
+* char *pathname - file to spawn
+* char **argv - vector of arguments
+*
+*Exit:
+* returns exit code of child process
+* if fails, returns -1
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _spawnv (
+ int modeflag,
+ const char *pathname,
+ const char * const *argv
+ )
+{
+ assert(pathname != NULL);
+ assert(*pathname != '\0');
+ assert(argv != NULL);
+ assert(*argv != NULL);
+ assert(**argv != '\0');
+
+ return(_spawnve(modeflag,pathname,argv,NULL));
+}
diff --git a/private/crt32/exec/spawnve.c b/private/crt32/exec/spawnve.c
new file mode 100644
index 000000000..00e321dd2
--- /dev/null
+++ b/private/crt32/exec/spawnve.c
@@ -0,0 +1,318 @@
+/***
+*spawnve.c - OS/2 low level routine eventually called by all _spawnXX routines
+* also contains all code for _execve, called by _execXX routines
+*
+* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+*
+* This is the low level routine which is eventually invoked by all the
+* _spawnXX routines.
+*
+* This is also the low-level routine which is eventually invoked by
+* all of the _execXX routines.
+*
+*Revision History:
+* 03-??-84 RLB created
+* 05-??-84 DCW modified to fix bug in initialization of envblock
+* pointer (used int 0 which would fail in long model) and
+* changed (char *)0 to NULL.
+* 03-31-86 SKS modified for OS/2; no OVERLAY mode,
+* new format for DOS Exec function
+* also check for Xenix or DOS style slash characters
+* 10-13-86 SKS pass program name to _cenvarg()
+* 11-19-86 SKS handle both kinds of slashes, with support for Kanji
+* 01-29-87 BCM don't try ".com" extension in protected mode (OS/2)
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 05/31/88 SJM Re-written to allow spawn of .CMD files, increase
+* speed. Added comexecmd routine.
+* 06/01/88 SJM added #ifdef statements for execve.obj compilation
+* 10-30-88 GJF Call _dospawn() for EXECVE, not _doexec().
+* 07-21-89 GJF Progagated fixes of 11-23-88 and 05-27-89 from CRT tree.
+* 11-16-89 GJF Added code to execve/spawnve to ensure a relative or
+* or absolute pathname is always used for the executable,
+* not just a filename (otherwise DOSEXECPGM will search
+* the PATH!). Also, cleaned up some of the erratic
+* formatting. Same as 9-15-89 change to CRT version
+* 11-20-89 GJF Added const attribute to types of appropriate args.
+* 02-08-90 GJF Fixed bug in comexecmd (must free(comname) if and only
+* if comname points to a malloc-ed block). Propagated
+* from 02-07-90 change in crt6 version.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h> and removed #include <register.h>.
+* 04-02-90 GJF Made comexecmd() _CALLTYPE4. Added #include <io.h>
+* and a prototype for comexecmd() to fix compiler
+* warnings (-W3).
+* 05-21-90 GJF Fixed stack checking pragma syntax.
+* 07-24-90 SBM Removed redundant include, minor optimization
+* 09-27-90 GJF New-style function declarators.
+* 12-28-90 SRW Added _CRUISER_ conditional around check_stack pragma
+* 01-17-91 GJF ANSI naming.
+* 08-21-91 JCR Call access() in before comexecmd (bug fix)
+* 01-24-92 JCR upgraded for Win32
+* 10-24-92 SKS Remove special treatment for batch files -
+* Windows NT will spawn %COMSPEC% automatically
+* 11-30-92 KRS Ported _MBCS support from 16-bit tree.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <io.h>
+#include <process.h>
+#include <errno.h>
+#include <msdos.h>
+#include <string.h>
+#include <stdlib.h>
+#include <internal.h>
+#include <mbstring.h>
+
+#ifdef _CRUISER_
+#pragma check_stack(on) /* turn on stack checking */
+#endif /* ndef _CRUISER_ */
+
+#define SLASHCHAR '\\'
+#define XSLASHCHAR '/'
+
+#ifndef EXECVE
+static int _CALLTYPE4 comexecmd(int mode, const char * name,
+ const char * const * argv, const char * const * envp);
+#else
+static int _CALLTYPE4 comexecmd(const char * name,
+ const char * const * argv, const char * const * envp);
+#endif /* EXECVE */
+
+/***
+*static int comexecmd(mode, name, argv, envp) - do the exec
+* or spawn after name fixup
+*
+*Purpose:
+* Spawns a child process with given parameters and environment. Either
+* overlays current process or loads in free memory while parent process
+* waits. If the named file is a .cmd file, modifies the calling sequence
+* and prepends the /c and filename arguments into the command string
+*
+* Exec doesn't take a mode; instead, the parent process goes away as
+* the child process is brought in.
+*
+*Entry:
+* int mode - mode to spawn (WAIT, NOWAIT, or OVERLAY)
+* only WAIT and OVERLAY currently supported
+*
+* **** mode is only used in the spawnve() version ****
+*
+* char *name - pathname of file to spawn. Includes the extension
+* char **argv - vector of parameter strings
+* char **envp - vector of environment variables
+*
+*Exit:
+* returns exit code of child process
+* if fails, returns -1
+*
+*Exceptions:
+* Returns a value of (-1) to indicate an error in exec'ing the child
+* process. errno may be set to:
+*
+* E2BIG = failed in argument/environment processing (_cenvarg)
+* argument list or environment too big;
+* EACCESS = locking or sharing violation on file;
+* EMFILE = too many files open;
+* ENOENT = failed to find program name - no such file or directory;
+* ENOEXEC = failed in exec - bad executable format;
+* ENOMEM = failed in memory allocation (during malloc, or in
+* setting up memory for executing child process).
+*
+*******************************************************************************/
+
+static int _CALLTYPE4 comexecmd (
+
+#ifndef EXECVE
+ REG3 int mode,
+#endif /* EXECVE */
+
+ REG2 const char *name,
+ const char * const *argv,
+ const char * const *envp
+ )
+{
+ char *argblk;
+ char *envblk;
+ REG4 int rc;
+
+ if (_cenvarg(argv, envp, &argblk, &envblk, name) == -1)
+ return -1;
+
+#ifndef EXECVE
+ rc = _dospawn(mode, name, argblk, envblk);
+#else
+ rc = _dospawn(_P_OVERLAY, name, argblk, envblk);
+#endif
+ /* free memory */
+
+ free(argblk);
+ free(envblk);
+
+ return rc;
+}
+
+/***
+*int _spawnve(mode, name, argv, envp) - low level _spawnXX library function
+*int _execve(name, argv, envp) - low level _execXX library function
+*
+*Purpose:
+* spawns or execs a child process; takes a single pointer to an argument
+* list as well as a pointer to the environment; unlike _spawnvpe,
+* _spawnve does not search the PATH= list in processing the name
+* parameter; mode specifies the parent's execution mode.
+*
+*Entry:
+* int mode - parent process's execution mode:
+* must be one of _P_OVERLAY, _P_WAIT, _P_NOWAIT;
+* not used for _execve
+* char *name - path name of program to spawn;
+* char **argv - pointer to array of pointers to child's arguments;
+* char **envp - pointer to array of pointers to child's environment
+* settings.
+*
+*Exit:
+* Returns : (int) a status value whose meaning is as follows:
+* 0 = normal termination of child process;
+* positive = exit code of child upon error termination
+* (abort or exit(nonzero));
+* -1 = child process was not spawned;
+* errno indicates what kind of error:
+* (E2BIG, EINVAL, ENOENT, ENOEXEC, ENOMEM).
+*
+*Exceptions:
+* Returns a value of (-1) to indicate an error in spawning the child
+* process. errno may be set to:
+*
+* E2BIG = failed in argument/environment processing (_cenvarg) -
+* argument list or environment too big;
+* EINVAL = invalid mode argument;
+* ENOENT = failed to find program name - no such file or directory;
+* ENOEXEC = failed in spawn - bad executable format;
+* ENOMEM = failed in memory allocation (during malloc, or in
+* setting up memory for spawning child process).
+*
+*******************************************************************************/
+
+/* Extension array - ordered in search order from right to left.
+
+ ext_strings = array of extensions
+*/
+
+#ifdef _CRUISER_
+static char *ext_strings[] = { NULL, ".exe", ".com" };
+enum {CMD, EXE, COM, EXTFIRST=CMD, EXTLAST=COM};
+#else
+static char *ext_strings[] = { ".cmd", ".bat", ".exe" , ".com" };
+enum {CMD, BAT, EXE, COM, EXTFIRST=CMD, EXTLAST=COM};
+#endif
+
+int _CALLTYPE1
+
+#ifndef EXECVE
+
+_spawnve (
+ REG3 int mode,
+
+#else
+
+_execve (
+
+#endif /* EXECVE */
+
+ const char *name,
+ const char * const *argv,
+ const char * const *envp
+ )
+{
+ char *ext; /* where the extension goes if we have to add one */
+ REG1 char *p;
+ char *q;
+ REG2 char *pathname = (char *)name;
+ REG4 int rc;
+ REG5 int i;
+
+#ifdef _CRUISER_
+ exstrings[CMD] = _osmode ? ".cmd" : ".bat";
+#endif
+
+ p = _mbsrchr(pathname, SLASHCHAR);
+ q = strrchr(pathname, XSLASHCHAR); /* No need for _mbsrchr with "/" */
+
+ /* ensure that pathname is an absolute or relative pathname. also,
+ * position p to point at the filename portion of pathname (i.e., just
+ * after the last occurence of a colon, slash or backslash character */
+
+ if (!q) {
+ if (!p)
+ if (!(p = strchr(pathname, ':'))) {
+
+ /* pathname is a filename only, force it to be
+ * a relative pathname. note that an extra byte
+ * is malloc-ed just in case pathname is NULL,
+ * to keep the heap from being trashed by
+ * strcpy */
+ if (!(pathname = malloc(strlen(pathname) + 3)))
+ return(-1);
+
+ strcpy(pathname, ".\\");
+ strcat(pathname, name);
+
+ /* set p to point to the start of the filename
+ * (i.e., past the ".\\" prefix) */
+ p = pathname + 2;
+ }
+ /* else pathname has drive specifier prefix and p is
+ * is pointing to the ':' */
+ }
+ else if (!p || q > p) /* p == NULL or q > p */
+ p = q;
+
+
+ rc = -1; /* init to error value */
+
+ if (ext = strrchr(p, '.')) {
+
+ /* extension given; only do filename */
+
+ if (_access(pathname, 0) != -1) {
+#ifndef EXECVE
+ rc = comexecmd(mode, pathname, argv, envp);
+#else
+ rc = comexecmd(pathname, argv, envp);
+#endif
+ }
+
+ }
+ else {
+
+ /* no extension; try .cmd/.bat, then .com and .exe */
+
+ if (!(p = malloc(strlen(pathname) + 5)))
+ return(-1);
+
+ strcpy(p, pathname);
+ ext = p + strlen(pathname);
+
+ for (i = EXTLAST; i >= EXTFIRST; --i) {
+ strcpy(ext, ext_strings[i]);
+
+ if (_access(p, 0) != -1) {
+#ifndef EXECVE
+ rc = comexecmd(mode, p, argv, envp);
+#else
+ rc = comexecmd(p, argv, envp);
+#endif /* EXECVE */
+ break;
+ }
+ }
+ free(p);
+ }
+
+ if (pathname != name)
+ free(pathname);
+
+ return rc;
+}
diff --git a/private/crt32/exec/spawnvp.c b/private/crt32/exec/spawnvp.c
new file mode 100644
index 000000000..f31dc2c60
--- /dev/null
+++ b/private/crt32/exec/spawnvp.c
@@ -0,0 +1,62 @@
+/***
+*spawnvp.c - spawn a child process; search along PATH
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _spawnvp() - spawn a child process; search along PATH
+*
+*Revision History:
+* 04-15-84 DFW written
+* 10-29-85 TC added spawnvpe capability
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 11-20-89 GJF Fixed copyright, alignment. Added const to arg types
+* for filename and argv.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h> and removed #include <register.h>
+* 05-21-90 GJF Fixed stack checking pragma syntax.
+* 08-24-90 SBM Removed check_stack pragma since workhorse _spawnve
+* does stack checks
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 02-14-90 SRW Use NULL instead of _environ to get default.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <stdlib.h>
+#include <process.h>
+
+/***
+*int _spawnvp(modeflag, filename, argv) - spawn a child process (search PATH)
+*
+*Purpose:
+* Spawns a child process, with search along PATH variable.
+* formats the parameters and calls _spawnve to do the actual work. The
+* NULL environment pointer indicates the new process will inherit the
+* parents process's environment. NOTE - at least one argument must be
+* present. This argument is always, by convention, the name of the file
+* being spawned.
+*
+*Entry:
+* int modeflag - mode to spawn (WAIT, NOWAIT, or OVERLAY)
+* only WAIT and OVERLAY currently supported
+* char *pathname - name of file to spawn
+* char **argv - vector of arguments
+*
+*Exit:
+* returns exit code of child process
+* returns -1 if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _spawnvp (
+ int modeflag,
+ REG3 const char *filename,
+ const char * const *argv
+ )
+{
+ return _spawnvpe(modeflag, filename, argv, NULL);
+}
diff --git a/private/crt32/exec/spawnvpe.c b/private/crt32/exec/spawnvpe.c
new file mode 100644
index 000000000..ffbdbb55a
--- /dev/null
+++ b/private/crt32/exec/spawnvpe.c
@@ -0,0 +1,209 @@
+/***
+*spawnvpe.c - spawn a child process with given environ (search PATH)
+*
+* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _spawnvpe() - spawn a child process with given environ (search
+* PATH)
+*
+*Revision History:
+* 04-15-84 DFW written
+* 10-29-85 TC added spawnvpe capability
+* 11-19-86 SKS handle both kinds of slashes
+* 12-01-86 JMB added Kanji file name support under conditional KANJI
+* switches. Corrected header info. Removed bogus check
+* for env = b after call to strncpy
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 09-05-88 SKS Treat EACCES the same as ENOENT -- keep trying
+* 10-17-88 GJF Removed copy of PATH string to local array, changed
+* bbuf to be a malloc-ed buffer. Removed bogus limits
+* on the size of that PATH string.
+* 10-25-88 GJF Don't search PATH when relative pathname is given (per
+* Stevesa). Also, if the name built from PATH component
+* and filename is a UNC name, allow any error.
+* 05-17-89 MT Added "include <jstring.h>" under KANJI switch
+* 05-24-89 PHG Reduce _amblksiz to use minimal memory (DOS only)
+* 08-29-89 GJF Use _getpath() to retrieve PATH components, fixing
+* several problems in handling unusual or bizarre
+* PATH's.
+* 11-20-89 GJF Added const attribute to types of filename, argv and
+* envptr.
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h> and removed #include <register.h>
+* 07-24-90 SBM Removed redundant includes, replaced <assertm.h> by
+* <assert.h>
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 09-25-91 JCR Changed ifdef "OS2" to "_DOS_" (unused in 32-bit tree)
+* 11-30-92 KRS Port _MBCS code from 16-bit tree.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <internal.h>
+#include <process.h>
+#include <mbstring.h>
+
+#define SLASH "\\"
+#define SLASHCHAR '\\'
+#define XSLASHCHAR '/'
+#define DELIMITER ";"
+
+#ifdef _MBCS
+/* note, the macro below assumes p is to pointer to a single-byte character
+ * or the 1st byte of a double-byte character, in a string.
+ */
+#define ISPSLASH(p) ( ((p) == _mbschr((p), SLASHCHAR)) || ((p) == \
+_mbschr((p), XSLASHCHAR)) )
+#else
+#define ISSLASH(c) ( ((c) == SLASHCHAR) || ((c) == XSLASHCHAR) )
+#endif
+
+/***
+*_spawnvpe(modeflag, filename, argv, envptr) - spawn a child process
+*
+*Purpose:
+* Spawns a child process with the given arguments and environ,
+* searches along PATH for given file until found.
+* Formats the parameters and calls _spawnve to do the actual work. The
+* NULL environment pointer indicates that the new process will inherit
+* the parents process's environment. NOTE - at least one argument must
+* be present. This argument is always, by convention, the name of the
+* file being spawned.
+*
+*Entry:
+* int modeflag - defines mode of spawn (WAIT, NOWAIT, or OVERLAY)
+* only WAIT and OVERLAY supported
+* char *filename - name of file to execute
+* char **argv - vector of parameters
+* char **envptr - vector of environment variables
+*
+*Exit:
+* returns exit code of spawned process
+* if fails, returns -1
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _spawnvpe (
+ int modeflag,
+ REG3 const char *filename,
+ const char * const *argv,
+ const char * const *envptr
+ )
+{
+ int i;
+ REG1 char *env;
+ REG2 char *buf = NULL;
+ char *pfin;
+#ifdef _DOS_
+ int tempamblksiz; /* old _amblksiz */
+#endif
+ assert(filename != NULL);
+ assert(*filename != '\0');
+ assert(argv != NULL);
+ assert(*argv != NULL);
+ assert(**argv != '\0');
+
+#ifdef _DOS_
+ tempamblksiz = _amblksiz;
+ _amblksiz = 0x10; /* reduce _amblksiz for efficient mallocs */
+#endif
+
+ if (
+ (i = _spawnve(modeflag, filename, argv, envptr)) != -1
+ /* everything worked just fine; return i */
+
+ || (errno != ENOENT)
+ /* couldn't spawn the process, return failure */
+
+ /* In a SBCS build, _mbschr will map to strchr. */
+
+ || (_mbschr(filename, XSLASHCHAR) != NULL)
+ /* filename contains a '/', return failure */
+
+#ifdef _DOS_
+ || (_mbschr(filename,SLASHCHAR) != NULL)
+ /* filename contains a '\', return failure */
+
+ || *filename && *(filename+1) == ':'
+ /* drive specification, return failure */
+#endif
+
+ || !(env = getenv("PATH"))
+ /* no PATH environment string name, return failure */
+
+ || ( (buf = (char *)malloc(_MAX_PATH)) == NULL )
+ /* cannot allocate buffer to build alternate pathnames, return
+ * failure */
+ ) {
+#ifdef _DOS_
+ _amblksiz = tempamblksiz; /* restore old _amblksiz */
+#endif
+ goto done;
+ }
+
+#ifdef _DOS_
+ _amblksiz = tempamblksiz; /* restore old _amblksiz */
+#endif
+
+
+ /* could not find the file as specified, search PATH. try each
+ * component of the PATH until we get either no error return, or the
+ * error is not ENOENT and the component is not a UNC name, or we run
+ * out of components to try.
+ */
+
+ while ( (env = _getpath(env, buf, _MAX_PATH - 1)) && (*buf) ) {
+
+ pfin = buf + strlen(buf) - 1;
+
+ /* if necessary, append a '/'
+ */
+#ifdef _MBCS
+ if (*pfin == SLASHCHAR) {
+ if (pfin != _mbsrchr(buf,SLASHCHAR))
+ /* fin is the second byte of a double-byte char */
+ strcat(buf, SLASH );
+ }
+ else if (*pfin !=XSLASHCHAR)
+ strcat(buf, SLASH);
+#else
+ if (*pfin != SLASHCHAR && *pfin != XSLASHCHAR)
+ strcat(buf, SLASH);
+#endif
+ /* check that the final path will be of legal size. if so,
+ * build it. otherwise, return to the caller (return value
+ * and errno rename set from initial call to _spawnve()).
+ */
+ if ( (strlen(buf) + strlen(filename)) < _MAX_PATH )
+ strcat(buf, filename);
+ else
+ break;
+
+ /* try spawning it. if successful, or if errno comes back with a
+ * value other than ENOENT and the pathname is not a UNC name,
+ * return to the caller.
+ */
+ if ( (i = _spawnve(modeflag, buf, argv, envptr)) != -1
+ || ((errno != ENOENT)
+#ifdef _MBCS
+ && (!ISPSLASH(buf) || !ISPSLASH(buf+1))) )
+#else
+ && (!ISSLASH(*buf) || !ISSLASH(*(buf+1)))) )
+#endif
+ break;
+
+ }
+
+done:
+ if (buf != NULL) free(buf);
+ return(i);
+}
diff --git a/private/crt32/exec/system.c b/private/crt32/exec/system.c
new file mode 100644
index 000000000..44536cf38
--- /dev/null
+++ b/private/crt32/exec/system.c
@@ -0,0 +1,95 @@
+/***
+*system.c - pass a command line to the shell
+*
+* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines system() - passes a command to the shell
+*
+*Revision History:
+* 12-01-83 RN written
+* 10-23-86 SKS Fixed use of strtok(), added check for NULL rtn from getenv
+* 12-18-86 SKS PROTMODE symbol used for dual-modal version
+* 02-23-86 JCR Put in support for NULL command pointer (MSDOS only)
+* 04-13-86 JCR Added const to declaration
+* 06-30-87 JCR Re-wrote system to use spawnvpe, removed XENIX conditional
+* code, lots of general cleaning up.
+* 07-01-87 PHG removed P->PROTMODE compile switch hack
+* 09-22-87 SKS remove extern variable declarations, add ";" to assert()'s
+* 11-10-87 SKS Removed IBMC20 switch, change PROTMODE to OS2
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 02-22-88 JCR Added cast to get rid of cl const warning
+* 09-05-88 SKS Treat EACCES the same as ENOENT -- keep trying
+* 03-08-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h>, removed some leftover DOS support and
+* fixed the copyright. Also, cleaned up the formatting
+* formatting a bit.
+* 07-23-90 SBM Compiles cleanly with -W3 (removed unreferenced
+* variable), removed redundant includes, replaced
+* <assertm.h> by <assert.h>, minor optimizations
+* 09-27-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+* 02-14-90 SRW Use NULL instead of _environ to get default.
+* 02-23-93 SKS Remove reference to _osmode and use of "command.com"
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <assert.h>
+#include <process.h>
+#include <io.h>
+#include <stdlib.h>
+#include <errno.h>
+
+/***
+*int system(command) - send the command line to a shell
+*
+*Purpose:
+* Executes a shell and passes the command line to it.
+* If command is NULL, determine if a command processor exists.
+*
+*Entry:
+* char *command - command to pass to the shell (if NULL, just determine
+* if command processor exists)
+*
+*Exit:
+* if command != NULL returns status of the shell
+* if command == NULL returns non-zero if CP exists, zero if CP doesn't exist
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 system (
+ const char *command
+ )
+{
+ int catch;
+ char *argv[4];
+
+ argv[0] = getenv("COMSPEC");
+
+ if (command == NULL) {
+ return (!_access(argv[0],0));
+ }
+
+ assert(*command != '\0');
+
+ argv[1] = "/c";
+ argv[2] = (char *) command;
+ argv[3] = NULL;
+
+ /* If there is a COMSPEC defined, try spawning the shell */
+
+ if (argv[0]) /* Do not try to spawn the null string */
+ if ((catch = _spawnve(_P_WAIT,argv[0],argv,NULL)) != -1
+ || (errno != ENOENT && errno != EACCES))
+ return(catch);
+
+ /* No COMSPEC so set argv[0] to what COMSPEC should be. */
+ argv[0] = "cmd.exe";
+
+ /* Let the _spawnvpe routine do the path search and spawn. */
+
+ return(_spawnvpe(_P_WAIT,argv[0],argv,NULL));
+}
diff --git a/private/crt32/exec/wait.c b/private/crt32/exec/wait.c
new file mode 100644
index 000000000..c6ba4cae4
--- /dev/null
+++ b/private/crt32/exec/wait.c
@@ -0,0 +1,199 @@
+/***
+*wait.c - OS/2 wait for child process to terminate
+*
+* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _wait() - wait for child process to terminate
+*
+*Revision History:
+* 06-08-89 PHG Module created, based on asm version
+* 03-08-90 GJF Made calling type _CALLTYPE2 (for now), added #include
+* <cruntime.h> and fixed the copyright. Also, cleaned up
+* the formatting a bit.
+* 04-02-90 GJF Now _CALLTYPE1.
+* 07-24-90 SBM Removed '32' from API names
+* 09-27-90 GJF New-style function declarators.
+* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
+* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
+* 01-17-91 GJF ANSI naming
+* 02-18-91 SRW Fixed code to close process handle. [_WIN32_]
+* 04-26-91 SRW Removed level 3 warnings [_WIN32_]
+* 12-17-91 GJF Fixed _cwait for Win32. However, _wait is still
+* broken [_WIN32_].
+* 07-21-92 GJF Removed _wait for Win32, not implemented and no good
+* way to implement.
+* 12-14-92 GJF For Win32, map ERROR_INVALID_HANDLE to ECHILD.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <process.h>
+#include <errno.h>
+#include <internal.h>
+#include <stdlib.h>
+
+/***
+*int _cwait(stat_loc, process_id, action_code) - wait for specific child
+* process
+*
+*Purpose:
+* The function _cwait() suspends the calling-process until the specified
+* child-process terminates. If the specifed child-process terminated
+* prior to the call to _cwait(), return is immediate.
+*
+*Entry:
+* int *stat_loc - pointer to where status is stored or NULL
+* process_id - specific process id to be interrogated (0 means any)
+* action_code - specific action to perform on process ID
+* either _WAIT_CHILD or _WAIT_GRANDCHILD
+*
+*Exit:
+* process ID of terminated child or -1 on error
+*
+* *stat_loc is updated to contain the following:
+* Normal termination: lo-byte = 0, hi-byte = child exit code
+* Abnormal termination: lo-byte = term status, hi-byte = 0
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CRTAPI1 _cwait (
+ int *stat_loc,
+ int process_id,
+ int action_code
+ )
+{
+#ifdef _CRUISER_
+ ULONG retstatus; /* return status from child */
+ ULONG retval; /* return value from wait */
+ char abnormend; /* child terminated abnormally */
+ ULONG dosretval; /* return value from OS/2 call */
+ RESULTCODES retcodes; /* return codes from child process */
+ PID pid_finished; /* process id of child that finished */
+
+ /* call OS/2 wait for child routine */
+ if (dosretval = DOSWAITCHILD(action_code, DCWW_WAIT, &retcodes,
+ &pid_finished, process_id)) {
+ /* error occured -- map error code and return */
+ _dosmaperr(dosretval);
+ return -1;
+ }
+
+ /* set status code values -- note that return value is
+ truncated to a byte for XENIX compatibility */
+
+ if (retcodes.codeTerminate != 0) {
+ abnormend = 1;
+ retstatus = retcodes.codeTerminate & 0xFF;
+ }
+ else {
+ abnormend = 0;
+ retstatus = (retcodes.codeResult & 0xFF) << 8 +
+ (retcodes.codeTerminate & 0xFF);
+ }
+
+ if (stat_loc != NULL)
+ *stat_loc = retstatus;
+
+ if (abnormend) {
+ /* abnormal termination, set errno and return -1 */
+ errno = EINTR;
+ _doserrno = 0; /* no OS/2 error */
+ return -1;
+ }
+
+ return retval;
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ int retval;
+ int retstatus;
+ unsigned long oserror;
+
+ DBG_UNREFERENCED_PARAMETER(action_code);
+
+ /* Explicitly check for process_id being -1 or -2. In Windows NT,
+ * -1 is a handle on the current process, -2 is a handle on the
+ * current thread, and it is perfectly legal to to wait (forever)
+ * on either */
+ if ( (process_id == -1) || (process_id == -2) ) {
+ errno = ECHILD;
+ return -1;
+ }
+
+ /* wait for child process, then fetch its exit code */
+ if ( (WaitForSingleObject((HANDLE)process_id, (DWORD)(-1L)) == 0) &&
+ GetExitCodeProcess((HANDLE)process_id, (LPDWORD)&retstatus) ) {
+ retval = process_id;
+ }
+ else {
+ /* one of the API calls failed. map the error and set up to
+ return failure. note the invalid handle error is mapped in-
+ line to ECHILD */
+ if ( (oserror = GetLastError()) == ERROR_INVALID_HANDLE ) {
+ errno = ECHILD;
+ _doserrno = oserror;
+ }
+ else
+ _dosmaperr(GetLastError());
+
+ retval = -1;
+ retstatus = -1;
+ }
+
+ CloseHandle((HANDLE)process_id);
+
+ if (stat_loc != NULL)
+ *stat_loc = retstatus;
+
+ return retval;
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+}
+
+
+#ifndef _WIN32_
+
+/***
+*int _wait(stat_loc) - wait for a child to terminate
+*
+*Purpose:
+* The function _wait() suspends the calling-process until one of the
+* immediate children terminates. If a child-process terminated prior to
+* the call on the function _wait(), return is immediate.
+*
+*Entry:
+* int *stat_loc - pointer to where status is stored or NULL
+*
+*Exit:
+* returns process id or -1 on errors.
+*
+* *stat_loc is updated to contain the following:
+* Normal termination: lo-byte = 0, hi-byte = child exit code
+* Abnormal termination: lo-byte = term status, hi-byte = 0
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+/* _wait calls _cwait to do all the real work */
+int _CRTAPI1 _wait (
+ int *stat_loc
+ )
+{
+ return _cwait(stat_loc, 0, _WAIT_CHILD);
+}
+
+
+#endif