summaryrefslogtreecommitdiffstats
path: root/private/crt32/exec/spawnvpe.c
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/spawnvpe.c
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/spawnvpe.c')
-rw-r--r--private/crt32/exec/spawnvpe.c209
1 files changed, 209 insertions, 0 deletions
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);
+}