[PATCH] D28854: raw_fd_ostream: Make file handles non-inheritable by default

Pavel Labath via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 18 04:12:50 PST 2017


labath created this revision.
Herald added a subscriber: mgorny.

This makes the file descriptors on unix platform non-inheritable by default
(O_CLOEXEC). I have also added a file open flag F_Inheritable to override this
behavior if necessary. If the platform supports O_CLOEXEC flag, we will use it
to set the descriptor flag during open(2). If the flag is not available, we will
revert to the (racy) fcntl(2) call.

There is no change in behavior on windows, as the handles were already
non-inheritable by default (but one can still use the new flag to make them
inheritable).


https://reviews.llvm.org/D28854

Files:
  cmake/config-ix.cmake
  include/llvm/Config/config.h.cmake
  include/llvm/Support/FileSystem.h
  lib/Support/Unix/Path.inc
  lib/Support/Windows/Path.inc


Index: lib/Support/Windows/Path.inc
===================================================================
--- lib/Support/Windows/Path.inc
+++ lib/Support/Windows/Path.inc
@@ -774,9 +774,14 @@
   if (Flags & F_RW)
     Access |= GENERIC_READ;
 
+  SECURITY_ATTRIBUTES sa;
+  sa.nLength = sizeof sa;
+  sa.lpSecurityDescriptor = nullptr;
+  sa.bInheritHandle = Flags & F_Inheritable ? TRUE : FALSE;
+
   HANDLE H = ::CreateFileW(PathUTF16.begin(), Access,
-                           FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                           CreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
+                           FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
+                           CreationDisposition, FILE_ATTRIBUTE_NORMAL, nullptr);
 
   if (H == INVALID_HANDLE_VALUE) {
     DWORD LastError = ::GetLastError();
Index: lib/Support/Unix/Path.inc
===================================================================
--- lib/Support/Unix/Path.inc
+++ lib/Support/Unix/Path.inc
@@ -629,12 +629,26 @@
   if (Flags & F_Excl)
     OpenFlags |= O_EXCL;
 
+#ifdef HAVE_O_CLOEXEC
+  if (!(Flags & F_Inheritable))
+    OpenFlags |= O_CLOEXEC;
+#endif
+
   SmallString<128> Storage;
   StringRef P = Name.toNullTerminatedStringRef(Storage);
   while ((ResultFD = open(P.begin(), OpenFlags, Mode)) < 0) {
     if (errno != EINTR)
       return std::error_code(errno, std::generic_category());
   }
+
+#ifndef HAVE_O_CLOEXEC
+  if (!(Flags & F_Inheritable)) {
+    int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
+    (void)r;
+    assert(r == 0);
+  }
+#endif
+
   return std::error_code();
 }
 
Index: include/llvm/Support/FileSystem.h
===================================================================
--- include/llvm/Support/FileSystem.h
+++ include/llvm/Support/FileSystem.h
@@ -638,7 +638,10 @@
   F_Text = 4,
 
   /// Open the file for read and write.
-  F_RW = 8
+  F_RW = 8,
+
+  /// Make the handle inheritable for child processes.
+  F_Inheritable = 16,
 };
 
 inline OpenFlags operator|(OpenFlags A, OpenFlags B) {
Index: include/llvm/Config/config.h.cmake
===================================================================
--- include/llvm/Config/config.h.cmake
+++ include/llvm/Config/config.h.cmake
@@ -153,6 +153,9 @@
 /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
 #cmakedefine HAVE_NDIR_H ${HAVE_NDIR_H}
 
+/* Define to 1 if you have the O_CLOEXEC open(2) flag */
+#cmakedefine HAVE_O_CLOEXEC ${HAVE_O_CLOEXEC}
+
 /* Define to 1 if you have the `posix_fallocate' function. */
 #cmakedefine HAVE_POSIX_FALLOCATE ${HAVE_POSIX_FALLOCATE}
 
Index: cmake/config-ix.cmake
===================================================================
--- cmake/config-ix.cmake
+++ cmake/config-ix.cmake
@@ -198,6 +198,7 @@
 check_symbol_exists(strerror_r string.h HAVE_STRERROR_R)
 check_symbol_exists(strerror_s string.h HAVE_DECL_STRERROR_S)
 check_symbol_exists(setenv stdlib.h HAVE_SETENV)
+check_symbol_exists(O_CLOEXEC "sys/types.h;sys/stat.h;fcntl.h" HAVE_O_CLOEXEC)
 if( PURE_WINDOWS )
   check_symbol_exists(_chsize_s io.h HAVE__CHSIZE_S)
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28854.84819.patch
Type: text/x-patch
Size: 3089 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170118/49e92bab/attachment.bin>


More information about the llvm-commits mailing list