Loading...
sys/posix_spawn.c Libc-1725.40.4 /dev/null
--- Libc/Libc-1725.40.4/sys/posix_spawn.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2006-2012 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * [SPN] Support for _POSIX_SPAWN
- */
-
-#include <spawn.h>
-#include <spawn_private.h>
-#include <sys/spawn_internal.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <limits.h>	/* for OPEN_MAX, PATH_MAX */
-#include <string.h>	/* for strlcpy() */
-#include <paths.h>	/* for _PATH_DEFPATH */
-#include <sys/stat.h>	/* for struct stat */
-
-/*
- * posix_spawnp
- *
- * Description:	Create a new process from the process image corresponding to
- *		the supplied 'file' argument and the parent processes path
- *		environment.
- *
- * Parameters:	pid				Pointer to pid_t to receive the
- *						PID of the spawned process, if
- *						successful and 'pid' != NULL
- *		file				Name of image file to spawn
- *		file_actions			spawn file actions object which
- *						describes file actions to be
- *						performed during the spawn
- *		attrp				spawn attributes object which
- *						describes attributes to be
- *						applied during the spawn
- *		argv				argument vector array; NULL
- *						terminated
- *		envp				environment vector array; NULL
- *						terminated
- *
- * Returns:	0				Success
- *		!0				An errno value indicating the
- *						cause of the failure to spawn
- *
- * Notes:	Much of this function is derived from code from execvP() from
- *		exec.c in libc; this common code should be factored out at
- *		some point to prevent code duplication or desynchronization vs.
- *		bug fixes applied to one set of code but not the other.
- */
-int
-posix_spawnp(pid_t * __restrict pid, const char * __restrict file,
-		const posix_spawn_file_actions_t *file_actions,
-		const posix_spawnattr_t * __restrict attrp,
-		char *const argv[ __restrict], char *const envp[ __restrict])
-{
-	const char *env_path;
-	char path_buf[PATH_MAX];
-	char *bp, *np, *op, *p;
-	char **memp;
-	size_t ln, lp;
-	int cnt;
-	int err = 0;
-	int eacces = 0;
-	struct stat sb;
-
-	/* If it's an absolute or relative path name, it's easy. */
-	if (strchr(file, '/')) {
-		bp = (char *)file;
-		env_path = op = NULL;
-		goto retry;
-	}
-
-	if ((env_path = getenv("PATH")) == NULL)
-		env_path = _PATH_DEFPATH;
-
-	bp = path_buf;
-
-	/* If it's an empty path name, fail in the usual POSIX way. */
-	if (*file == '\0')
-		return (ENOENT);
-
-	op = env_path;
-	ln = strlen(file);
-	while (op != NULL) {
-		np = strchrnul(op, ':');
-
-		/*
-		 * It's a SHELL path -- double, leading and trailing colons
-		 * mean the current directory.
-		 */
-		if (np == op) {
-			/* Empty component. */
-			p = ".";
-			lp = 1;
-		} else {
-			/* Non-empty component. */
-			p = op;
-			lp = np - op;
-		}
-
-		/* Advance to the next component or terminate after this. */
-		if (*np == '\0')
-			op = NULL;
-		else
-			op = np + 1;
-
-		/*
-		 * If the path is too long complain.  This is a possible
-		 * security issue; given a way to make the path too long
-		 * the user may spawn the wrong program.
-		 */
-		if (lp + ln + 2 > sizeof(path_buf)) {
-			err = ENAMETOOLONG;
-			goto done;
-		}
-		bcopy(p, path_buf, lp);
-		path_buf[lp] = '/';
-		bcopy(file, path_buf + lp + 1, ln);
-		path_buf[lp + ln + 1] = '\0';
-
-retry:		err = posix_spawn(pid, bp, file_actions, attrp, argv, envp);
-		switch (err) {
-		case E2BIG:
-		case ENOMEM:
-		case ETXTBSY:
-			goto done;
-		case ELOOP:
-		case ENAMETOOLONG:
-		case ENOENT:
-		case ENOTDIR:
-			break;
-		case ENOEXEC:
-			for (cnt = 0; argv[cnt]; ++cnt)
-				;
-
-			/*
-			 * cnt may be 0 above; always allocate at least
-			 * 3 entries so that we can at least fit "sh", bp, and
-			 * the NULL terminator.  We can rely on cnt to take into
-			 * account the NULL terminator in all other scenarios,
-			 * as we drop argv[0].
-			 */
-			memp = alloca(MAX(3, cnt + 2) * sizeof(char *));
-			if (memp == NULL) {
-				/* errno = ENOMEM; XXX override ENOEXEC? */
-				goto done;
-			}
-			if (cnt > 0) {
-				memp[0] = argv[0];
-				memp[1] = bp;
-				bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
-			} else {
-				memp[0] = "sh";
-				memp[1] = bp;
-				memp[2] = NULL;
-			}
-			err = posix_spawn(pid, _PATH_BSHELL, file_actions, attrp, memp, envp);
-			goto done;
-		default:
-			/*
-			 * EACCES may be for an inaccessible directory or
-			 * a non-executable file.  Call stat() to decide
-			 * which.  This also handles ambiguities for EFAULT
-			 * and EIO, and undocumented errors like ESTALE.
-			 * We hope that the race for a stat() is unimportant.
-			 */
-			if (stat(bp, &sb) != 0)
-				break;
-			if (err == EACCES) {
-				eacces = 1;
-				continue;
-			}
-			goto done;
-		}
-	}
-	if (eacces)
-		err = EACCES;
-	/*
-	 * Preserve errno from posix_spawn(3) if it wasn't a PATH search, or
-	 * if it was a PATH search and we bailed out early.  Note that every
-	 * branch in the loop jumps to the `done` label to preserve errno, so
-	 * this is more of a defensive check.
-	 */
-	else if (env_path != NULL && op == NULL)
-		err = ENOENT;
-done:
-	return (err);
-}