Browse Source

Open fstream files in O_CLOEXEC mode when possible.

Reviewers: EricWF, mclow.lists, ldionne

Reviewed By: ldionne

Subscribers: smeenai, dexonsmith, christof, ldionne, libcxx-commits

Tags: #libc

Differential Revision: https://reviews.llvm.org/D59839

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@372027 91177308-0d34-0410-b5e6-96231b3b80d8
Dan Albert 6 years ago
parent
commit
ba4e717aaf
2 changed files with 23 additions and 12 deletions
  1. 11 0
      include/__config
  2. 12 12
      include/fstream

+ 11 - 0
include/__config

@@ -1447,6 +1447,17 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
 
 #define _LIBCPP_UNUSED_VAR(x) ((void)(x))
 
+// Configures the fopen close-on-exec mode character, if any. This string will
+// be appended to any mode string used by fstream for fopen/fdopen.
+//
+// Not all platforms support this, but it helps avoid fd-leaks on platforms that
+// do.
+#if defined(__BIONIC__)
+#  define _LIBCPP_FOPEN_CLOEXEC_MODE "e"
+#else
+#  define _LIBCPP_FOPEN_CLOEXEC_MODE
+#endif
+
 #endif // __cplusplus
 
 #endif // _LIBCPP_CONFIG

+ 12 - 12
include/fstream

@@ -508,34 +508,34 @@ const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(
   switch (__mode & ~ios_base::ate) {
   case ios_base::out:
   case ios_base::out | ios_base::trunc:
-    return "w";
+    return "w" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::out | ios_base::app:
   case ios_base::app:
-    return "a";
+    return "a" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::in:
-    return "r";
+    return "r" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::in | ios_base::out:
-    return "r+";
+    return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::in | ios_base::out | ios_base::trunc:
-    return "w+";
+    return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::in | ios_base::out | ios_base::app:
   case ios_base::in | ios_base::app:
-    return "a+";
+    return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::out | ios_base::binary:
   case ios_base::out | ios_base::trunc | ios_base::binary:
-    return "wb";
+    return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::out | ios_base::app | ios_base::binary:
   case ios_base::app | ios_base::binary:
-    return "ab";
+    return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::in | ios_base::binary:
-    return "rb";
+    return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::in | ios_base::out | ios_base::binary:
-    return "r+b";
+    return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
-    return "w+b";
+    return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
   case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
   case ios_base::in | ios_base::app | ios_base::binary:
-    return "a+b";
+    return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
   default:
     return nullptr;
   }