summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2003-02-07 21:02:32 +0000
committertrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2003-02-07 21:02:32 +0000
commita20af0d4bc073b20464a3ee8f01e8613cca8729d (patch)
tree6df785b7ec3ba76bc02583b610869d58050c86cb
parent04f847c22b3a837858b73fa02c76f8bfcb45726e (diff)
downloadlibapr-a20af0d4bc073b20464a3ee8f01e8613cca8729d.tar.gz
add apr_procattr_error_check_set() for telling apr_proc_create() to
try to anticipate any errors that might occur after fork() (no-op everywhere but Unix) git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64341 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES9
-rw-r--r--include/apr_thread_proc.h14
-rw-r--r--include/arch/unix/apr_arch_threadproc.h1
-rw-r--r--threadproc/beos/proc.c7
-rw-r--r--threadproc/netware/proc.c7
-rw-r--r--threadproc/os2/proc.c9
-rw-r--r--threadproc/unix/proc.c33
-rw-r--r--threadproc/win32/proc.c7
8 files changed, 82 insertions, 5 deletions
diff --git a/CHANGES b/CHANGES
index b91a1df66..51cdd495e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -8,11 +8,10 @@ Changes with APR 0.9.2
.pdb symbol files.) Documentation on how-to-use these symbol files
will be forthcoming. [Allen Edwards, William Rowe]
- *) 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]
+ *) Add two new proc attributes to improve diagnostics for
+ apr_proc_create() failures on platforms where fork()+exec() is used.
+ See the doc for apr_procattr_child_errfn_set() and
+ apr_procattr_error_check_set(). [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 0e4b514a6..435082f57 100644
--- a/include/apr_thread_proc.h
+++ b/include/apr_thread_proc.h
@@ -512,6 +512,20 @@ APR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr,
APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
apr_child_errfn_t *errfn);
+/**
+ * Specify that apr_proc_create() should do whatever it can to report
+ * failures to the caller of apr_proc_create(), rather than find out in
+ * the child.
+ * @param chk Flag to indicate whether or not extra work should be done
+ * to try to report failures to the caller.
+ * @remark This flag only affects apr_proc_create() on platforms where
+ * fork() is used. This leads to extra overhead in the calling
+ * process, but that may help the application handle such
+ * errors more gracefully.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
+ apr_int32_t chk);
+
#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 960db1e50..6de6cc275 100644
--- a/include/arch/unix/apr_arch_threadproc.h
+++ b/include/arch/unix/apr_arch_threadproc.h
@@ -135,6 +135,7 @@ struct apr_procattr_t {
struct rlimit *limit_nofile;
#endif
apr_child_errfn_t *errfn;
+ apr_int32_t errchk;
};
#endif /* ! THREAD_PROC_H */
diff --git a/threadproc/beos/proc.c b/threadproc/beos/proc.c
index 7bfa3f77f..031debc60 100644
--- a/threadproc/beos/proc.c
+++ b/threadproc/beos/proc.c
@@ -210,6 +210,13 @@ APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
+ apr_int32_t chk)
+{
+ /* won't ever be used on this platform, so don't save the flag */
+ return APR_SUCCESS;
+}
+
APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, const char *progname,
const char * const *args,
const char * const *env,
diff --git a/threadproc/netware/proc.c b/threadproc/netware/proc.c
index 537d22e93..c51d8e9ea 100644
--- a/threadproc/netware/proc.c
+++ b/threadproc/netware/proc.c
@@ -290,6 +290,13 @@ APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
+ apr_int32_t chk)
+{
+ /* won't ever be used on this platform, so don't save the flag */
+ 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 7afe711fe..45ab03d26 100644
--- a/threadproc/os2/proc.c
+++ b/threadproc/os2/proc.c
@@ -287,6 +287,15 @@ APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
+APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
+ apr_int32_t chk)
+{
+ /* won't ever be used on this platform, so don't save the flag */
+ 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 a57f76ad1..015fe04c3 100644
--- a/threadproc/unix/proc.c
+++ b/threadproc/unix/proc.c
@@ -302,6 +302,13 @@ APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
+ apr_int32_t chk)
+{
+ attr->errchk = chk;
+ return APR_SUCCESS;
+}
+
APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
const char *progname,
const char * const *args,
@@ -316,6 +323,32 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
new->err = attr->parent_err;
new->out = attr->parent_out;
+ if (attr->errchk) {
+ if (attr->currdir) {
+ if (access(attr->currdir, R_OK|X_OK) == -1) {
+ /* chdir() in child wouldn't have worked */
+ return errno;
+ }
+ }
+
+ if (attr->cmdtype == APR_PROGRAM ||
+ attr->cmdtype == APR_PROGRAM_ENV ||
+ *progname == '/') {
+ /* for both of these values of cmdtype, caller must pass
+ * full path, so it is easy to check;
+ * caller can choose to pass full path for other
+ * values of cmdtype
+ */
+ if (access(progname, R_OK|X_OK) == -1) {
+ /* exec*() in child wouldn't have worked */
+ return errno;
+ }
+ }
+ else {
+ /* todo: search PATH for progname then try to access it */
+ }
+ }
+
if ((new->pid = fork()) < 0) {
return errno;
}
diff --git a/threadproc/win32/proc.c b/threadproc/win32/proc.c
index fa80a9b12..02b6f57f0 100644
--- a/threadproc/win32/proc.c
+++ b/threadproc/win32/proc.c
@@ -288,6 +288,13 @@ APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
+ apr_int32_t chk)
+{
+ /* won't ever be used on this platform, so don't save the flag */
+ return APR_SUCCESS;
+}
+
APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
const char *progname,
const char * const *args,