diff options
author | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2003-02-06 18:50:30 +0000 |
---|---|---|
committer | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2003-02-06 18:50:30 +0000 |
commit | 6c24107afad9f9daab8e2d169158f3dfb058302e (patch) | |
tree | 9ac24e21d682e1a04d2d6583e8f9d8bb3b1f442f | |
parent | 258b05d7442a92daf7ecd55eeb39025300b0c216 (diff) | |
download | libapr-6c24107afad9f9daab8e2d169158f3dfb058302e.tar.gz |
Allow apr_proc_create() to call an app-provided error reporting
function when apr_proc_create() fails in the new child process
after fork(). The app-provided error reporting function will only
be called on platforms where apr_proc_create() first calls
fork() to create the new process.
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64330 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | include/apr_thread_proc.h | 25 | ||||
-rw-r--r-- | include/arch/unix/apr_arch_threadproc.h | 1 | ||||
-rw-r--r-- | threadproc/beos/proc.c | 6 | ||||
-rw-r--r-- | threadproc/netware/proc.c | 7 | ||||
-rw-r--r-- | threadproc/os2/proc.c | 9 | ||||
-rw-r--r-- | threadproc/unix/proc.c | 21 | ||||
-rw-r--r-- | threadproc/win32/proc.c | 7 |
8 files changed, 82 insertions, 0 deletions
@@ -1,5 +1,11 @@ Changes with APR 0.9.2 + *) Allow apr_proc_create() to call an app-provided error reporting + function when apr_proc_create() fails in the new child process + after fork(). The app-provided error reporting function will only + be called on platforms where apr_proc_create() first calls + fork() to create the new process. [Jeff Trawick] + *) Rename rules.mk to apr_rules.mk and make apr_rules.mk be installed. [Thom May] diff --git a/include/apr_thread_proc.h b/include/apr_thread_proc.h index f64d13435..0e4b514a6 100644 --- a/include/apr_thread_proc.h +++ b/include/apr_thread_proc.h @@ -177,6 +177,19 @@ struct apr_proc_t { #endif }; +/** + * The prototype for APR child errfn functions. (See the description + * of apr_procattr_child_errfn_set() for more information.) + * It is passed the following parameters: + * @param pool Pool associated with the apr_proc_t. If your child + * error function needs user data, associate it with this + * pool. + * @param err APR error code describing the error + * @param description Text description of type of processing which failed + */ +typedef void (apr_child_errfn_t)(apr_pool_t *proc, apr_status_t err, + const char *description); + /** Opaque Thread structure. */ typedef struct apr_thread_t apr_thread_t; /** Opaque Thread attributes structure. */ @@ -487,6 +500,18 @@ APR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr, struct rlimit *limit); #endif +/** + * Specify an error function to be called in the child process if APR + * encounters an error in the child prior to running the specified program. + * @param child_errfn The function to call in the child process. + * @param userdata Parameter to be passed to errfn. + * @remark At the present time, it will only be called from apr_proc_create() + * on platforms where fork() is used. It will never be called on other + * platforms. + */ +APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr, + apr_child_errfn_t *errfn); + #if APR_HAS_FORK /** * This is currently the only non-portable call in APR. This executes diff --git a/include/arch/unix/apr_arch_threadproc.h b/include/arch/unix/apr_arch_threadproc.h index 002c8f701..960db1e50 100644 --- a/include/arch/unix/apr_arch_threadproc.h +++ b/include/arch/unix/apr_arch_threadproc.h @@ -134,6 +134,7 @@ struct apr_procattr_t { #ifdef RLIMIT_NOFILE struct rlimit *limit_nofile; #endif + apr_child_errfn_t *errfn; }; #endif /* ! THREAD_PROC_H */ diff --git a/threadproc/beos/proc.c b/threadproc/beos/proc.c index e97085581..7bfa3f77f 100644 --- a/threadproc/beos/proc.c +++ b/threadproc/beos/proc.c @@ -203,6 +203,12 @@ APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *pool) return APR_INPARENT; } +APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr, + apr_child_errfn_t *errfn) +{ + /* won't ever be called on this platform, so don't save the function pointer */ + return APR_SUCCESS; +} APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, const char *progname, const char * const *args, diff --git a/threadproc/netware/proc.c b/threadproc/netware/proc.c index 4ca612d64..537d22e93 100644 --- a/threadproc/netware/proc.c +++ b/threadproc/netware/proc.c @@ -283,6 +283,13 @@ static apr_status_t limit_proc(apr_procattr_t *attr) return APR_SUCCESS; } +APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr, + apr_child_errfn_t *errfn) +{ + /* won't ever be called on this platform, so don't save the function pointer */ + return APR_SUCCESS; +} + APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *newproc, const char *progname, const char * const *args, diff --git a/threadproc/os2/proc.c b/threadproc/os2/proc.c index 75b4237bf..7afe711fe 100644 --- a/threadproc/os2/proc.c +++ b/threadproc/os2/proc.c @@ -278,6 +278,15 @@ static char *double_quotes(apr_pool_t *pool, const char *str) +APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr, + apr_child_errfn_t *errfn) +{ + /* won't ever be called on this platform, so don't save the function pointer */ + return APR_SUCCESS; +} + + + APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *proc, const char *progname, const char * const *args, const char * const *env, diff --git a/threadproc/unix/proc.c b/threadproc/unix/proc.c index 8c07e8cf9..a57f76ad1 100644 --- a/threadproc/unix/proc.c +++ b/threadproc/unix/proc.c @@ -295,6 +295,13 @@ static apr_status_t limit_proc(apr_procattr_t *attr) return APR_SUCCESS; } +APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr, + apr_child_errfn_t *errfn) +{ + attr->errfn = errfn; + return APR_SUCCESS; +} + APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, const char *progname, const char * const *args, @@ -368,11 +375,17 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, if (attr->currdir != NULL) { if (chdir(attr->currdir) == -1) { + if (attr->errfn) { + attr->errfn(pool, errno, "change of working directory failed"); + } exit(-1); /* We have big problems, the child should exit. */ } } if ((status = limit_proc(attr)) != APR_SUCCESS) { + if (attr->errfn) { + attr->errfn(pool, errno, "setting of resource limits failed"); + } exit(-1); /* We have big problems, the child should exit. */ } @@ -422,6 +435,14 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, execvp(progname, (char * const *)args); } + if (attr->errfn) { + char *desc; + + desc = apr_psprintf(pool, "exec of '%s' failed", + progname); + attr->errfn(pool, errno, desc); + } + exit(-1); /* if we get here, there is a problem, so exit with an * error code. */ } diff --git a/threadproc/win32/proc.c b/threadproc/win32/proc.c index aa2e4a62a..fa80a9b12 100644 --- a/threadproc/win32/proc.c +++ b/threadproc/win32/proc.c @@ -281,6 +281,13 @@ static char *apr_caret_escape_args(apr_pool_t *p, const char *str) return cmd; } +APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr, + apr_child_errfn_t *errfn) +{ + /* won't ever be called on this platform, so don't save the function pointer */ + return APR_SUCCESS; +} + APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, const char *progname, const char * const *args, |