2  * Copyright (c) 2006-2012 Apple Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  * [SPN] Support for _POSIX_SPAWN 
  29 #include <spawn_private.h> 
  30 #include <sys/spawn_internal.h> 
  33 #include <limits.h>     /* for OPEN_MAX, PATH_MAX */ 
  34 #include <string.h>     /* for strlcpy() */ 
  35 #include <paths.h>      /* for _PATH_DEFPATH */ 
  36 #include <sys/stat.h>   /* for struct stat */ 
  41  * Description: Create a new process from the process image corresponding to 
  42  *              the supplied 'file' argument and the parent processes path 
  45  * Parameters:  pid                             Pointer to pid_t to receive the 
  46  *                                              PID of the spawned process, if 
  47  *                                              successful and 'pid' != NULL 
  48  *              file                            Name of image file to spawn 
  49  *              file_actions                    spawn file actions object which 
  50  *                                              describes file actions to be 
  51  *                                              performed during the spawn 
  52  *              attrp                           spawn attributes object which 
  53  *                                              describes attributes to be 
  54  *                                              applied during the spawn 
  55  *              argv                            argument vector array; NULL 
  57  *              envp                            environment vector array; NULL 
  61  *              !0                              An errno value indicating the 
  62  *                                              cause of the failure to spawn 
  64  * Notes:       Much of this function is derived from code from execvP() from 
  65  *              exec.c in libc; this common code should be factored out at 
  66  *              some point to prevent code duplication or desynchronization vs. 
  67  *              bug fixes applied to one set of code but not the other. 
  70 posix_spawnp(pid_t 
* __restrict pid
, const char * __restrict file
, 
  71                 const posix_spawn_file_actions_t 
*file_actions
, 
  72                 const posix_spawnattr_t 
* __restrict attrp
, 
  73                 char *const argv
[ __restrict
], char *const envp
[ __restrict
]) 
  86         char path_buf
[PATH_MAX
]; 
  88         if ((env_path 
= getenv("PATH")) == NULL
) 
  89                 env_path 
= _PATH_DEFPATH
; 
  91         /* If it's an absolute or relative path name, it's easy. */ 
  92         if (index(file
, '/')) { 
  99         /* If it's an empty path name, fail in the usual POSIX way. */ 
 103         if ((cur 
= alloca(strlen(env_path
) + 1)) == NULL
) 
 105         strcpy(cur
, env_path
); 
 106         while ((p 
= strsep(&cur
, ":")) != NULL
) { 
 108                  * It's a SHELL path -- double, leading and trailing colons 
 109                  * mean the current directory. 
 120                  * If the path is too long complain.  This is a possible 
 121                  * security issue; given a way to make the path too long 
 122                  * the user may spawn the wrong program. 
 124                 if (lp 
+ ln 
+ 2 > sizeof(path_buf
)) { 
 128                 bcopy(p
, path_buf
, lp
); 
 130                 bcopy(file
, path_buf 
+ lp 
+ 1, ln
); 
 131                 path_buf
[lp 
+ ln 
+ 1] = '\0'; 
 133 retry
:          err 
= posix_spawn(pid
, bp
, file_actions
, attrp
, argv
, envp
); 
 145                         for (cnt 
= 0; argv
[cnt
]; ++cnt
) 
 147                         memp 
= alloca((cnt 
+ 2) * sizeof(char *)); 
 149                                 /* errno = ENOMEM; XXX override ENOEXEC? */ 
 154                         bcopy(argv 
+ 1, memp 
+ 2, cnt 
* sizeof(char *)); 
 155                         err 
= posix_spawn(pid
, _PATH_BSHELL
, file_actions
, attrp
, memp
, envp
); 
 159                          * EACCES may be for an inaccessible directory or 
 160                          * a non-executable file.  Call stat() to decide 
 161                          * which.  This also handles ambiguities for EFAULT 
 162                          * and EIO, and undocumented errors like ESTALE. 
 163                          * We hope that the race for a stat() is unimportant. 
 165                         if (stat(bp
, &sb
) != 0)