FileStream.Unix: open with CLOEXEC unless FileShare.Inheritable set (dotnet/coreclr...
authorTom Deseyn <tom.deseyn@gmail.com>
Fri, 17 Mar 2017 23:54:45 +0000 (00:54 +0100)
committerStephen Toub <stoub@microsoft.com>
Fri, 17 Mar 2017 23:54:45 +0000 (19:54 -0400)
* FileStream.Unix: open with CLOEXEC unless FileShare.Inheritable set

* PR feedback

Commit migrated from https://github.com/dotnet/coreclr/commit/f29a051ee1829937cde011ee28bbd17557d35e0b

src/coreclr/src/mscorlib/shared/System/IO/FileStream.Unix.cs

index ef186ff..7d860ac 100644 (file)
@@ -45,7 +45,7 @@ namespace System.IO
                 _asyncState = new AsyncState();
 
             // Translate the arguments into arguments for an open call.
-            Interop.Sys.OpenFlags openFlags = PreOpenConfigurationFromOptions(mode, _access, options); // FileShare currently ignored
+            Interop.Sys.OpenFlags openFlags = PreOpenConfigurationFromOptions(mode, _access, share, options);
 
             // If the file gets created a new, we'll select the permissions for it.  Most Unix utilities by default use 666 (read and 
             // write for all), so we do the same (even though this doesn't match Windows, where by default it's possible to write out
@@ -120,9 +120,10 @@ namespace System.IO
         /// <summary>Translates the FileMode, FileAccess, and FileOptions values into flags to be passed when opening the file.</summary>
         /// <param name="mode">The FileMode provided to the stream's constructor.</param>
         /// <param name="access">The FileAccess provided to the stream's constructor</param>
+        /// <param name="share">The FileShare provided to the stream's constructor</param>
         /// <param name="options">The FileOptions provided to the stream's constructor</param>
         /// <returns>The flags value to be passed to the open system call.</returns>
-        private static Interop.Sys.OpenFlags PreOpenConfigurationFromOptions(FileMode mode, FileAccess access, FileOptions options)
+        private static Interop.Sys.OpenFlags PreOpenConfigurationFromOptions(FileMode mode, FileAccess access, FileShare share, FileOptions options)
         {
             // Translate FileMode.  Most of the values map cleanly to one or more options for open.
             Interop.Sys.OpenFlags flags = default(Interop.Sys.OpenFlags);
@@ -166,6 +167,12 @@ namespace System.IO
                     break;
             }
 
+            // Handle Inheritable, other FileShare flags are handled by Init
+            if ((share & FileShare.Inheritable) == 0)
+            {
+                flags |= Interop.Sys.OpenFlags.O_CLOEXEC;
+            }
+
             // Translate some FileOptions; some just aren't supported, and others will be handled after calling open.
             // - Asynchronous: Handled in ctor, setting _useAsync and SafeFileHandle.IsAsync to true
             // - DeleteOnClose: Doesn't have a Unix equivalent, but we approximate it in Dispose