This patch implements (for Unix, at least) what I mentioned in a previous post, namely, to make available all information about a terminated child but to classify it so that a portable app doesn't have to play games with WIFEXITED() et al.
As I mentioned before, I don't know if we're doing the right thing on Unix w.r.t. capturing information about processes which are stopped. Index: server/mpm_common.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm_common.c,v retrieving revision 1.69 diff -u -r1.69 mpm_common.c --- server/mpm_common.c 2001/09/21 14:29:33 1.69 +++ server/mpm_common.c 2001/10/15 17:24:42 @@ -124,7 +124,7 @@ continue; proc.pid = pid; - waitret = apr_proc_wait(&proc, NULL, APR_NOWAIT); + waitret = apr_proc_wait(&proc, APR_NOWAIT); if (waitret != APR_CHILD_NOTDONE) { MPM_NOTE_CHILD_KILLED(i); continue; @@ -204,12 +204,13 @@ if (wait_or_timeout_counter == INTERVAL_OF_WRITABLE_PROBES) { wait_or_timeout_counter = 0; } - rv = apr_proc_wait_all_procs(ret, status, APR_NOWAIT, p); + rv = apr_proc_wait_all_procs(ret, APR_NOWAIT, p); if (APR_STATUS_IS_EINTR(rv)) { ret->pid = -1; return; } if (APR_STATUS_IS_CHILD_DONE(rv)) { + *status = ret->native_exit_status; return; } #ifdef NEED_WAITPID Index: srclib/apr/include/apr_thread_proc.h =================================================================== RCS file: /home/cvs/apr/include/apr_thread_proc.h,v retrieving revision 1.75 diff -u -r1.75 apr_thread_proc.h --- srclib/apr/include/apr_thread_proc.h 2001/09/20 08:59:30 1.75 +++ srclib/apr/include/apr_thread_proc.h 2001/10/15 17:25:09 @@ -81,6 +81,7 @@ typedef enum {APR_SHELLCMD, APR_PROGRAM} apr_cmdtype_e; typedef enum {APR_WAIT, APR_NOWAIT} apr_wait_how_e; +typedef enum {APR_CHILD_NORMAL_EXIT, APR_CHILD_SIGNAL_EXIT, APR_CHILD_STOPPED} apr_exit_how_e; #define APR_NO_PIPE 0 #define APR_FULL_BLOCK 1 @@ -124,6 +125,17 @@ apr_file_t *out; /** Parent's side of pipe to child's stdouterr */ apr_file_t *err; + /** How did the child exit? (normally, via uncaught signal, etc.) */ + apr_exit_how_e exit_how; + /** What did the OS return for the child exit status? */ + apr_wait_t native_exit_status; + /** What is the exit code (for normal exit) or terminating signal? */ + union { + int exit_code; +#ifdef WIFSIGNALED + int signal; +#endif + } exit_status; #ifdef WIN32 /** Must retain the handle as any clone may not have the * the same permissions @@ -481,11 +493,6 @@ /** * Wait for a child process to die * @param proc The process handle that corresponds to the desired child process - * @param exitcode The returned exit status of the child, if a child process - * dies. On platforms that don't support obtaining this - * information, the exitcode parameter will be returned as - * APR_ENOTIMPL. This parameter may be NULL if the exit code - * is not needed. * @param waithow How should we wait. One of: * <PRE> * APR_WAIT -- block until the child process dies. @@ -499,7 +506,6 @@ * </PRE> */ APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc, - apr_wait_t *exitcode, apr_wait_how_e waithow); /** @@ -507,9 +513,6 @@ * about that child. * @param proc Pointer to NULL on entry, will be filled out with child's * information - * @param status The returned exit status of the child, if a child process dies - * On platforms that don't support obtaining this information, - * the status parameter will be returned as APR_ENOTIMPL. * @param waithow How should we wait. One of: * <PRE> * APR_WAIT -- block until the child process dies. @@ -519,9 +522,8 @@ * @param p Pool to allocate child information out of. */ APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc, - apr_wait_t *status, - apr_wait_how_e waithow, - apr_pool_t *p); + apr_wait_how_e waithow, + apr_pool_t *p); /** * Detach the process from the controlling terminal. Index: srclib/apr/memory/unix/apr_pools.c =================================================================== RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v retrieving revision 1.113 diff -u -r1.113 apr_pools.c --- srclib/apr/memory/unix/apr_pools.c 2001/09/28 15:22:35 1.113 +++ srclib/apr/memory/unix/apr_pools.c 2001/10/15 17:25:17 @@ -1505,7 +1505,7 @@ #ifndef NEED_WAITPID /* Pick up all defunct processes */ for (p = procs; p; p = p->next) { - if (apr_proc_wait(p->pid, NULL, APR_NOWAIT) != APR_CHILD_NOTDONE) { + if (apr_proc_wait(p->pid, APR_NOWAIT) != APR_CHILD_NOTDONE) { p->kill_how = kill_never; } } @@ -1550,7 +1550,7 @@ /* Now wait for all the signaled processes to die */ for (p = procs; p; p = p->next) { if (p->kill_how != kill_never) { - (void) apr_proc_wait(p->pid, NULL, APR_WAIT); + (void) apr_proc_wait(p->pid, APR_WAIT); } } #ifdef WIN32 Index: srclib/apr/threadproc/unix/proc.c =================================================================== RCS file: /home/cvs/apr/threadproc/unix/proc.c,v retrieving revision 1.49 diff -u -r1.49 proc.c --- srclib/apr/threadproc/unix/proc.c 2001/09/21 16:14:50 1.49 +++ srclib/apr/threadproc/unix/proc.c 2001/10/15 17:25:23 @@ -362,16 +362,14 @@ } APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc, - apr_wait_t *status, apr_wait_how_e waithow, apr_pool_t *p) { proc->pid = -1; - return apr_proc_wait(proc, status, waithow); + return apr_proc_wait(proc, waithow); } APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc, - apr_wait_t *exitcode, apr_wait_how_e waithow) { pid_t pstatus; @@ -383,16 +381,21 @@ } if ((pstatus = waitpid(proc->pid, &exit_int, waitpid_options)) > 0) { - if (proc->pid == -1) { - proc->pid = pstatus; - } + proc->pid = pstatus; + proc->native_exit_status = exit_int; if (WIFEXITED(exit_int)) { - if (exitcode != NULL) { - *exitcode = WEXITSTATUS(exit_int); - } - return APR_CHILD_DONE; + proc->exit_how = APR_CHILD_NORMAL_EXIT; + proc->exit_status.exit_code = WEXITSTATUS(exit_int); + } + else if (WIFSIGNALED(exit_int)) { + proc->exit_how = APR_CHILD_SIGNAL_EXIT; + proc->exit_status.signal = WTERMSIG(exit_int); + } + else if (WIFSTOPPED(exit_int)) { + proc->exit_how = APR_CHILD_STOPPED; + proc->exit_status.signal = WSTOPSIG(exit_int); } - return APR_CHILD_NOTDONE; + return APR_CHILD_DONE; } else if (pstatus == 0) { return APR_CHILD_NOTDONE; -- Jeff Trawick | [EMAIL PROTECTED] | PGP public key at web site: http://www.geocities.com/SiliconValley/Park/9289/ Born in Roswell... married an alien...