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...

Reply via email to