diff options
author | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2003-02-07 21:02:32 +0000 |
---|---|---|
committer | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2003-02-07 21:02:32 +0000 |
commit | a20af0d4bc073b20464a3ee8f01e8613cca8729d (patch) | |
tree | 6df785b7ec3ba76bc02583b610869d58050c86cb | |
parent | 04f847c22b3a837858b73fa02c76f8bfcb45726e (diff) | |
download | libapr-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-- | CHANGES | 9 | ||||
-rw-r--r-- | include/apr_thread_proc.h | 14 | ||||
-rw-r--r-- | include/arch/unix/apr_arch_threadproc.h | 1 | ||||
-rw-r--r-- | threadproc/beos/proc.c | 7 | ||||
-rw-r--r-- | threadproc/netware/proc.c | 7 | ||||
-rw-r--r-- | threadproc/os2/proc.c | 9 | ||||
-rw-r--r-- | threadproc/unix/proc.c | 33 | ||||
-rw-r--r-- | threadproc/win32/proc.c | 7 |
8 files changed, 82 insertions, 5 deletions
@@ -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, |