Anyone care to apply this to unix and hack it a bit?  I only found four cases 
where
we (probably) should be calling apr_file_open() to create an inheritable file.

As I mention, sockets are still an issue, so are child processes, shared memory
handles, and a list of others.  But if we knock these off one bit at a time, we 
will
probably knock down the child handle abuse.

Serious (?) bug I noticed, if a buffered file has pending data to write, and a 
child
is spawned, both the parent _AND_ child will attempt to flush the buffer.  It 
used
to happen when the child pool was destroyed, with this patch it will occur when 
the
process is spawned.  It appears we need a pre-fork() registered action, to flush
buffers and the like.  That's only partially effective though, unless we do some
heavy mutex protection :(

I'm still traveling till Sunday morning, so I can't revisit for a bit.



----- Original Message ----- 
From: "William A. Rowe, Jr." <[EMAIL PROTECTED]>
To: <dev@apr.apache.org>
Sent: Friday, July 13, 2001 3:45 PM
Subject: Inherited Handles and APR


> After a respectable lunch at Boudin's, Ryan and I think we have the general 
> answers
> to child handles.
> 
> The apr_foo_open/create calls need an APR_INHERIT flag bit to mark resources 
> as
> inheritable.  This offers two advantages;
> 
>   1. the app doesn't need to worry about fork/exec cleanups v.s. inherit bits 
> for
>      createprocess() based Win32 (and other non-forks.)
> 
>   2. mainline code is more readable, as the user no longer registers their own
>      cleanup_for_exec handlers to simply close handles.
> 
> The patch, for apr_file_open, follows.  Rbb is working on a similar for 
> Sockets, and
> calls that generate 'handles' will need to be reviewed as well...
> 
> I obviously have the much larger job of applying the APR_INHERIT flag 
> judiciously
> throughout the entire server and removing child cleanups where appropriate ...
> 
> Bill
> 
Index: file_io/unix/open.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/open.c,v
retrieving revision 1.77
diff -u -r1.77 open.c
--- file_io/unix/open.c 2001/06/27 19:40:34     1.77
+++ file_io/unix/open.c 2001/07/13 20:41:08
@@ -167,7 +167,8 @@
     (*new)->dataRead = 0;
     (*new)->direction = 0;
     apr_pool_cleanup_register((*new)->cntxt, (void *)(*new), 
apr_unix_file_cleanup,
-                        apr_pool_cleanup_null);
+                              (flag & APR_INHERIT) ? apr_pool_cleanup_null 
+                                                   : apr_unix_file_cleanup);
     return APR_SUCCESS;
 }
 
Index: file_io/win32/open.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/open.c,v
retrieving revision 1.77
diff -u -r1.77 open.c
--- file_io/win32/open.c        2001/06/27 19:40:41     1.77
+++ file_io/win32/open.c        2001/07/13 20:41:10
@@ -173,6 +173,7 @@
                                    apr_int32_t flag, apr_fileperms_t perm,
                                    apr_pool_t *cont)
 {
+    SECURITY_ATTRIBUTES sa, *psa = NULL;
     /* XXX: The default FILE_FLAG_SEQUENTIAL_SCAN is _wrong_ for
      *      sdbm and any other random files!  We _must_ rethink
      *      this approach.
@@ -236,6 +237,12 @@
          */
         attributes |= FILE_FLAG_OVERLAPPED;
     }
+    if (flag & APR_INHERIT) {
+        sa.nLength = sizeof(sa);
+        sa.bInheritHandle = TRUE;
+        sa.lpSecurityDescriptor = NULL;
+        psa = &sa;
+    }
 
 #if APR_HAS_UNICODE_FS
     if (os_level >= APR_WIN_NT) {
@@ -244,12 +251,12 @@
                                                / sizeof(apr_wchar_t), fname))
             return rv;
         handle = CreateFileW(wfname, oflags, sharemode,
-                             NULL, createflags, attributes, 0);
+                             psa, createflags, attributes, 0);
     }
     else
 #endif
         handle = CreateFileA(fname, oflags, sharemode,
-                             NULL, createflags, attributes, 0);
+                             psa, createflags, attributes, 0);
 
     if (handle == INVALID_HANDLE_VALUE) {
         return apr_get_os_error();
Index: include/apr_file_io.h
===================================================================
RCS file: /home/cvs/apr/include/apr_file_io.h,v
retrieving revision 1.103
diff -u -r1.103 apr_file_io.h
--- include/apr_file_io.h       2001/06/27 19:40:46     1.103
+++ include/apr_file_io.h       2001/07/13 20:41:13
@@ -89,6 +89,10 @@
 #define APR_SHARELOCK  1024        /* Platform dependent support for higher
                                       level locked read/write access to support
                                       writes across process/machines */
+#define APR_INHERIT    4096        /* Create the file inheritable by the child
+                                      process. fork()ed implementations 
+                                      automatically register a child cleanup
+                                      in the _absence_ of this flag. */
 
 /* flags for apr_file_seek */
 #define APR_SET SEEK_SET
@@ -141,6 +145,10 @@
  *           APR_SHARELOCK        Platform dependent support for higher
  *                                level locked read/write access to support
  *                                writes across process/machines
+ *           APR_INHERIT          Create the file inheritable by the child
+ *                                processes.  fork()ed implementations 
+ *                                automatically register a child cleanup
+ *                                in the _absence_ of this flag.
  * </PRE>
  * @param perm Access permissions for file.
  * @param cont The pool to use.
Index: modules/cache/mod_file_cache.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/cache/mod_file_cache.c,v
retrieving revision 1.56
diff -u -r1.56 mod_file_cache.c
--- modules/cache/mod_file_cache.c      2001/06/27 20:18:03     1.56
+++ modules/cache/mod_file_cache.c      2001/07/14 06:57:56
@@ -207,7 +207,7 @@
        return;
     }
 
-    rc = apr_file_open(&fd, fspec, APR_READ | APR_BINARY | APR_XTHREAD,
+    rc = apr_file_open(&fd, fspec, APR_READ | APR_BINARY | APR_XTHREAD | 
APR_INHERIT,
                        APR_OS_DEFAULT, cmd->pool);
     if (rc != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server,
Index: modules/loggers/mod_log_config.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/loggers/mod_log_config.c,v
retrieving revision 1.60
diff -u -r1.60 mod_log_config.c
--- modules/loggers/mod_log_config.c    2001/05/22 01:31:06     1.60
+++ modules/loggers/mod_log_config.c    2001/07/14 06:58:18
@@ -206,7 +206,7 @@
 
 module AP_MODULE_DECLARE_DATA log_config_module;
 
-static int xfer_flags = (APR_WRITE | APR_APPEND | APR_CREATE);
+static int xfer_flags = (APR_WRITE | APR_APPEND | APR_CREATE | APR_INHERIT);
 static apr_fileperms_t xfer_perms = APR_OS_DEFAULT;
 static apr_hash_t *log_hash;
 
Index: modules/mappers/mod_rewrite.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/mappers/mod_rewrite.c,v
retrieving revision 1.77
diff -u -r1.77 mod_rewrite.c
--- modules/mappers/mod_rewrite.c       2001/05/18 18:38:41     1.77
+++ modules/mappers/mod_rewrite.c       2001/07/14 06:58:31
@@ -3096,7 +3096,7 @@
     const char *fname;
     apr_status_t rc;
     piped_log *pl;
-    int    rewritelog_flags = ( APR_WRITE | APR_APPEND | APR_CREATE );
+    int    rewritelog_flags = ( APR_WRITE | APR_APPEND | APR_CREATE | 
APR_INHERIT );
     apr_fileperms_t rewritelog_mode  = ( APR_UREAD | APR_UWRITE | APR_GREAD | 
APR_WREAD );
 
     conf = ap_get_module_config(s->module_config, &rewrite_module);
Index: server/log.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/log.c,v
retrieving revision 1.93
diff -u -r1.93 log.c
--- server/log.c        2001/06/06 22:24:54     1.93
+++ server/log.c        2001/07/14 06:58:47
@@ -266,7 +266,7 @@
     else {
        fname = ap_server_root_relative(p, s->error_fname);
         rc = apr_file_open(&s->error_log, fname, 
-                      APR_APPEND | APR_READ | APR_WRITE | APR_CREATE,
+                      APR_APPEND | APR_READ | APR_WRITE | APR_CREATE | 
APR_INHERIT,
                       APR_OS_DEFAULT, p);
         if (rc != APR_SUCCESS) {
             ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, 

Reply via email to