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