1--- threadproc/unix/proc.c.orig 2007-10-14 11:00:37.000000000 -0700 2+++ threadproc/unix/proc.c 2009-04-06 12:34:57.000000000 -0700 3@@ -20,6 +20,9 @@ 4 #include "apr_signal.h" 5 #include "apr_random.h" 6 7+#include <crt_externs.h> 8+#include <spawn.h> 9+ 10 /* Heavy on no'ops, here's what we want to pass if there is APR_NO_FILE 11 * requested for a specific child handle; 12 */ 13@@ -599,6 +602,84 @@ 14 return APR_SUCCESS; 15 } 16 17+APR_DECLARE(apr_status_t) apr_proc_spawn(apr_proc_t *new, 18+ const char *progname, 19+ const char * const *args, 20+ const char * const *env, 21+ apr_procattr_t *attr, 22+ apr_pool_t *pool) 23+{ 24+ posix_spawn_file_actions_t file_actions; 25+ int status = APR_EGENERAL; 26+ 27+ new->in = attr->parent_in; 28+ new->err = attr->parent_err; 29+ new->out = attr->parent_out; 30+ 31+ // XXX: attr->errchk 32+ 33+ // XXX: Are those apr_pool_cleanup_* calls needed? 34+ 35+ posix_spawn_file_actions_init(&file_actions); 36+ 37+ if ((attr->child_in) && (attr->child_in->filedes == -1)) { 38+ posix_spawn_file_actions_addclose(&file_actions, STDIN_FILENO); 39+ } 40+ else if (attr->child_in) { 41+ posix_spawn_file_actions_adddup2(&file_actions, attr->child_in->filedes, STDIN_FILENO); 42+ posix_spawn_file_actions_addclose(&file_actions, attr->child_in->filedes); 43+ } 44+ 45+ if ((attr->child_out) && (attr->child_out->filedes == -1)) { 46+ posix_spawn_file_actions_addclose(&file_actions, STDOUT_FILENO); 47+ } 48+ else if (attr->child_out) { 49+ posix_spawn_file_actions_adddup2(&file_actions, attr->child_out->filedes, STDOUT_FILENO); 50+ posix_spawn_file_actions_addclose(&file_actions, attr->child_out->filedes); 51+ } 52+ 53+ if ((attr->child_err) && (attr->child_err->filedes == -1)) { 54+ posix_spawn_file_actions_addclose(&file_actions, STDERR_FILENO); 55+ } 56+ else if (attr->child_err) { 57+ posix_spawn_file_actions_adddup2(&file_actions, attr->child_err->filedes, STDERR_FILENO); 58+ posix_spawn_file_actions_addclose(&file_actions, attr->child_err->filedes); 59+ } 60+ 61+ // XXX: signal 62+ // XXX: currdir, gid, uid, limit_proc 63+ 64+ /* Only support APR_PROGRAM_PATH for now. */ 65+ if (attr->cmdtype == APR_PROGRAM_PATH) { 66+ /* Pass existing environment; as documented, APR_PROGRAM_PATH ignores the env argument. */ 67+ status = posix_spawnp(&new->pid, progname, &file_actions, NULL, args, (const char **)*_NSGetEnviron()); 68+ if (status != 0) { 69+ if (attr->errfn) { 70+ char *desc; 71+ 72+ desc = apr_psprintf(pool, "posix_spawn of '%s' failed", progname); 73+ attr->errfn(pool, status, desc); 74+ } 75+ } 76+ } 77+ 78+ posix_spawn_file_actions_destroy(&file_actions); 79+ 80+ if (attr->child_in && (attr->child_in->filedes != -1)) { 81+ apr_file_close(attr->child_in); 82+ } 83+ 84+ if (attr->child_out && (attr->child_out->filedes != -1)) { 85+ apr_file_close(attr->child_out); 86+ } 87+ 88+ if (attr->child_err && (attr->child_err->filedes != -1)) { 89+ apr_file_close(attr->child_err); 90+ } 91+ 92+ return status; 93+} 94+ 95 APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc, 96 int *exitcode, 97 apr_exit_why_e *exitwhy, 98