Loading...
--- Libc/Libc-997.90.3/sys/posix_spawn.c
+++ /dev/null
@@ -1,180 +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 *bp;
- char *cur;
- char *p;
- char **memp;
- int lp;
- int ln;
- int cnt;
- int err = 0;
- int eacces = 0;
- struct stat sb;
- char path_buf[PATH_MAX];
-
- if ((env_path = getenv("PATH")) == NULL)
- env_path = _PATH_DEFPATH;
-
- /* If it's an absolute or relative path name, it's easy. */
- if (index(file, '/')) {
- bp = (char *)file;
- cur = NULL;
- goto retry;
- }
- bp = path_buf;
-
- /* If it's an empty path name, fail in the usual POSIX way. */
- if (*file == '\0')
- return (ENOENT);
-
- if ((cur = alloca(strlen(env_path) + 1)) == NULL)
- return ENOMEM;
- strcpy(cur, env_path);
- while ((p = strsep(&cur, ":")) != NULL) {
- /*
- * It's a SHELL path -- double, leading and trailing colons
- * mean the current directory.
- */
- if (*p == '\0') {
- p = ".";
- lp = 1;
- } else {
- lp = strlen(p);
- }
- ln = strlen(file);
-
- /*
- * 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)
- ;
- memp = alloca((cnt + 2) * sizeof(char *));
- if (memp == NULL) {
- /* errno = ENOMEM; XXX override ENOEXEC? */
- goto done;
- }
- memp[0] = "sh";
- memp[1] = bp;
- bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
- 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;
- else
- err = ENOENT;
-done:
- return (err);
-}