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,