summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2003-02-06 18:50:30 +0000
committertrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2003-02-06 18:50:30 +0000
commit6c24107afad9f9daab8e2d169158f3dfb058302e (patch)
tree9ac24e21d682e1a04d2d6583e8f9d8bb3b1f442f
parent258b05d7442a92daf7ecd55eeb39025300b0c216 (diff)
downloadlibapr-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--CHANGES6
-rw-r--r--include/apr_thread_proc.h25
-rw-r--r--include/arch/unix/apr_arch_threadproc.h1
-rw-r--r--threadproc/beos/proc.c6
-rw-r--r--threadproc/netware/proc.c7
-rw-r--r--threadproc/os2/proc.c9
-rw-r--r--threadproc/unix/proc.c21
-rw-r--r--threadproc/win32/proc.c7
8 files changed, 82 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index e3551ec74..15150f218 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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,