(if the app wants to burn the cycles, that is)

With a new attribute set, apr_proc_create() will check for some common problems prior to forking. This enables the caller to handle errors more gracefully with no funky code.

I have half a mind to make this attribute set by default with APR 1.0 and let apps that run apr_proc_create() constantly and don't want the extra overhead (e.g., mod_cgi) turn it off if they want.

Comments?

Better name for the attribute than apr_procattr_error_check_set() pretty please?
Index: include/apr_thread_proc.h
===================================================================
RCS file: /home/cvs/apr/include/apr_thread_proc.h,v
retrieving revision 1.91
diff -u -r1.91 apr_thread_proc.h
--- include/apr_thread_proc.h   6 Feb 2003 18:50:30 -0000       1.91
+++ include/apr_thread_proc.h   7 Feb 2003 12:56:56 -0000
@@ -512,6 +512,20 @@
 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 
Index: include/arch/unix/apr_arch_threadproc.h
===================================================================
RCS file: /home/cvs/apr/include/arch/unix/apr_arch_threadproc.h,v
retrieving revision 1.4
diff -u -r1.4 apr_arch_threadproc.h
--- include/arch/unix/apr_arch_threadproc.h     6 Feb 2003 18:50:30 -0000       
1.4
+++ include/arch/unix/apr_arch_threadproc.h     7 Feb 2003 12:56:56 -0000
@@ -135,6 +135,7 @@
     struct rlimit *limit_nofile;
 #endif
     apr_child_errfn_t *errfn;
+    apr_int32_t errchk;
 };
 
 #endif  /* ! THREAD_PROC_H */
Index: threadproc/unix/proc.c
===================================================================
RCS file: /home/cvs/apr/threadproc/unix/proc.c,v
retrieving revision 1.64
diff -u -r1.64 proc.c
--- threadproc/unix/proc.c      6 Feb 2003 18:50:30 -0000       1.64
+++ threadproc/unix/proc.c      7 Feb 2003 12:56:57 -0000
@@ -302,6 +302,13 @@
     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,
@@ -315,6 +322,32 @@
     new->in = attr->parent_in;
     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;

Reply via email to