On Tue, 2008-08-05 at 14:57 -0500, William A. Rowe, Jr. wrote:

> You have it upside down though, apr_file_inherit_[un]set should toggle
> the CLOEXEC flag.

I was thinking something like this (untested).

-- 
Bojan
Index: file_io/unix/open.c
===================================================================
--- file_io/unix/open.c	(revision 683098)
+++ file_io/unix/open.c	(working copy)
@@ -125,6 +125,12 @@
         oflags |= O_BINARY;
     }
 #endif
+
+#ifdef O_CLOEXEC
+    if (!(flag & APR_FILE_NOCLEANUP)) {
+        oflags |= O_CLOEXEC;
+    }
+#endif
     
 #if APR_HAS_LARGE_FILES && defined(_LARGEFILE64_SOURCE)
     oflags |= O_LARGEFILE;
@@ -324,8 +330,30 @@
     return apr_file_open_flags_stdin(thefile, 0, pool);
 }
 
-APR_IMPLEMENT_INHERIT_SET(file, flags, pool, apr_unix_file_cleanup)
+/* Implemented by hand in order to take advantage of O_CLOEXEC where
+ * available. */
+APR_DECLARE(apr_status_t) apr_file_inherit_set(apr_file_t *thefile)
+{
+    if (thefile->flags & APR_FILE_NOCLEANUP) {
+        return APR_EINVAL;
+    }
+    if (!(thefile->flags & APR_INHERIT)) {
+#ifdef O_CLOEXEC
+        int flags = fcntl(thefile->filedes, F_GETFD);
 
+        flags &= ~(FD_CLOEXEC);
+
+        fcntl(thefile->filedes, F_SETFD, flags);
+#endif
+        thefile->flags |= APR_INHERIT;
+        apr_pool_child_cleanup_set(thefile->pool,
+                                   (void *)thefile,
+                                   apr_unix_file_cleanup,
+                                   apr_pool_cleanup_null);
+    }
+    return APR_SUCCESS;
+}
+
 /* We need to do this by hand instead of using APR_IMPLEMENT_INHERIT_UNSET
  * because the macro sets both cleanups to the same function, which is not
  * suitable on Unix (see PR 41119). */
@@ -335,6 +363,13 @@
         return APR_EINVAL;
     }
     if (thefile->flags & APR_INHERIT) {
+#ifdef O_CLOEXEC
+        int flags = fcntl(thefile->filedes, F_GETFD);
+
+        flags |= FD_CLOEXEC;
+
+        fcntl(thefile->filedes, F_SETFD, flags);
+#endif
         thefile->flags &= ~APR_INHERIT;
         apr_pool_child_cleanup_set(thefile->pool,
                                    (void *)thefile,

Reply via email to