Index: lldb/trunk/include/lldb/Host/File.h
===================================================================
--- lldb/trunk/include/lldb/Host/File.h
+++ lldb/trunk/include/lldb/Host/File.h
@@ -64,9 +64,9 @@
         m_is_real_terminal(eLazyBoolCalculate),
         m_supports_colors(eLazyBoolCalculate) {}
 
-  File(int fd, bool transfer_ownership)
+  File(int fd, uint32_t options, bool transfer_ownership)
       : IOObject(eFDTypeFile, transfer_ownership), m_descriptor(fd),
-        m_stream(kInvalidStream), m_options(0), m_own_stream(false),
+        m_stream(kInvalidStream), m_options(options), m_own_stream(false),
         m_is_interactive(eLazyBoolCalculate),
         m_is_real_terminal(eLazyBoolCalculate) {}
 
@@ -125,7 +125,7 @@
 
   WaitableHandle GetWaitableHandle() override;
 
-  void SetDescriptor(int fd, bool transfer_ownership);
+  void SetDescriptor(int fd, uint32_t options, bool transfer_ownership);
 
   FILE *GetStream();
 
@@ -332,8 +332,6 @@
 
   size_t PrintfVarArg(const char *format, va_list args);
 
-  void SetOptions(uint32_t options) { m_options = options; }
-
   static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; };
 
 protected:
Index: lldb/trunk/source/Core/StreamFile.cpp
===================================================================
--- lldb/trunk/source/Core/StreamFile.cpp
+++ lldb/trunk/source/Core/StreamFile.cpp
@@ -21,7 +21,7 @@
     : Stream(flags, addr_size, byte_order), m_file() {}
 
 StreamFile::StreamFile(int fd, bool transfer_ownership)
-    : Stream(), m_file(fd, transfer_ownership) {}
+    : Stream(), m_file(fd, File::eOpenOptionWrite, transfer_ownership) {}
 
 StreamFile::StreamFile(FILE *fh, bool transfer_ownership)
     : Stream(), m_file(fh, transfer_ownership) {}
Index: lldb/trunk/source/Host/common/File.cpp
===================================================================
--- lldb/trunk/source/Host/common/File.cpp
+++ lldb/trunk/source/Host/common/File.cpp
@@ -93,11 +93,12 @@
 
 IOObject::WaitableHandle File::GetWaitableHandle() { return GetDescriptor(); }
 
-void File::SetDescriptor(int fd, bool transfer_ownership) {
+void File::SetDescriptor(int fd, uint32_t options, bool transfer_ownership) {
   if (IsValid())
     Close();
   m_descriptor = fd;
   m_should_close_fd = transfer_ownership;
+  m_options = options;
 }
 
 FILE *File::GetStream() {
Index: lldb/trunk/source/Host/common/FileSystem.cpp
===================================================================
--- lldb/trunk/source/Host/common/FileSystem.cpp
+++ lldb/trunk/source/Host/common/FileSystem.cpp
@@ -436,11 +436,10 @@
 
   Status error;
   if (!File::DescriptorIsValid(descriptor)) {
-    File.SetDescriptor(descriptor, false);
+    File.SetDescriptor(-1, options, false);
     error.SetErrorToErrno();
   } else {
-    File.SetDescriptor(descriptor, should_close_fd);
-    File.SetOptions(options);
+    File.SetDescriptor(descriptor, options, should_close_fd);
   }
   return error;
 }
Index: lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp
===================================================================
--- lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -86,8 +86,8 @@
 ConnectionFileDescriptor::ConnectionFileDescriptor(int fd, bool owns_fd)
     : Connection(), m_pipe(), m_mutex(), m_shutting_down(false),
       m_waiting_for_accept(false), m_child_processes_inherit(false) {
-  m_write_sp = std::make_shared<File>(fd, owns_fd);
-  m_read_sp = std::make_shared<File>(fd, false);
+  m_write_sp = std::make_shared<File>(fd, File::eOpenOptionWrite, owns_fd);
+  m_read_sp = std::make_shared<File>(fd, File::eOpenOptionRead, false);
 
   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION |
                                                   LIBLLDB_LOG_OBJECT));
@@ -218,8 +218,10 @@
             m_read_sp = std::move(tcp_socket);
             m_write_sp = m_read_sp;
           } else {
-            m_read_sp = std::make_shared<File>(fd, false);
-            m_write_sp = std::make_shared<File>(fd, false);
+            m_read_sp =
+                std::make_shared<File>(fd, File::eOpenOptionRead, false);
+            m_write_sp =
+                std::make_shared<File>(fd, File::eOpenOptionWrite, false);
           }
           m_uri = *addr;
           return eConnectionStatusSuccess;
@@ -268,8 +270,8 @@
           ::fcntl(fd, F_SETFL, flags);
         }
       }
-      m_read_sp = std::make_shared<File>(fd, true);
-      m_write_sp = std::make_shared<File>(fd, false);
+      m_read_sp = std::make_shared<File>(fd, File::eOpenOptionRead, true);
+      m_write_sp = std::make_shared<File>(fd, File::eOpenOptionWrite, false);
       return eConnectionStatusSuccess;
     }
 #endif
Index: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
===================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -901,7 +901,7 @@
     }
 
     if (temp_fd != -1) {
-      lldb_private::File file(temp_fd, true);
+      lldb_private::File file(temp_fd, File::eOpenOptionWrite, true);
       const size_t expr_text_len = strlen(expr_text);
       size_t bytes_written = expr_text_len;
       if (file.Write(expr_text, bytes_written).Success()) {
Index: lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
===================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
+++ lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
@@ -425,11 +425,16 @@
           }
         }
         Status posix_error;
+        int oflag = file_action->GetActionArgument();
         int created_fd =
-            open(file_spec.GetPath().c_str(), file_action->GetActionArgument(),
-                 S_IRUSR | S_IWUSR);
+            open(file_spec.GetPath().c_str(), oflag, S_IRUSR | S_IWUSR);
         if (created_fd >= 0) {
-          file.SetDescriptor(created_fd, true);
+          uint32_t file_options = 0;
+          if ((oflag & O_RDWR) || (oflag & O_RDONLY))
+            file_options |= File::eOpenOptionRead;
+          if ((oflag & O_RDWR) || (oflag & O_RDONLY))
+            file_options |= File::eOpenOptionWrite;
+          file.SetDescriptor(created_fd, file_options, true);
           [options setValue:[NSNumber numberWithInteger:created_fd] forKey:key];
           return error; // Success
         } else {
Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
===================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -537,7 +537,7 @@
   int err = -1;
   int save_errno = 0;
   if (fd >= 0) {
-    File file(fd, true);
+    File file(fd, 0, true);
     Status error = file.Close();
     err = 0;
     save_errno = error.GetError();
@@ -568,7 +568,7 @@
       }
 
       std::string buffer(count, 0);
-      File file(fd, false);
+      File file(fd, File::eOpenOptionRead, false);
       Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset);
       const ssize_t bytes_read = error.Success() ? count : -1;
       const int save_errno = error.GetError();
@@ -600,7 +600,7 @@
     if (packet.GetChar() == ',') {
       std::string buffer;
       if (packet.GetEscapedBinaryData(buffer)) {
-        File file(fd, false);
+        File file(fd, File::eOpenOptionWrite, false);
         size_t count = buffer.size();
         Status error =
             file.Write(static_cast<const void *>(&buffer[0]), count, offset);
Index: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
===================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -1043,9 +1043,9 @@
   file.Close();
   // We don't own the file descriptor returned by this function, make sure the
   // File object knows about that.
-  file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false);
   PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>();
-  file.SetOptions(PythonFile::GetOptionsFromMode(py_mode.GetString()));
+  auto options = PythonFile::GetOptionsFromMode(py_mode.GetString());
+  file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), options, false);
   return file.IsValid();
 }
 
Index: lldb/trunk/source/Target/Process.cpp
===================================================================
--- lldb/trunk/source/Target/Process.cpp
+++ lldb/trunk/source/Target/Process.cpp
@@ -4299,9 +4299,10 @@
   IOHandlerProcessSTDIO(Process *process, int write_fd)
       : IOHandler(process->GetTarget().GetDebugger(),
                   IOHandler::Type::ProcessIO),
-        m_process(process), m_write_file(write_fd, false) {
+        m_process(process),
+        m_write_file(write_fd, File::eOpenOptionWrite, false) {
     m_pipe.CreateNew(false);
-    m_read_file.SetDescriptor(GetInputFD(), false);
+    m_read_file.SetDescriptor(GetInputFD(), File::eOpenOptionRead, false);
   }
 
   ~IOHandlerProcessSTDIO() override = default;
Index: lldb/trunk/unittests/Host/FileTest.cpp
===================================================================
--- lldb/trunk/unittests/Host/FileTest.cpp
+++ lldb/trunk/unittests/Host/FileTest.cpp
@@ -34,3 +34,24 @@
   File file(stream, true);
   EXPECT_EQ(file.GetWaitableHandle(), fd);
 }
+
+TEST(File, GetStreamFromDescriptor) {
+  const auto *Info = testing::UnitTest::GetInstance()->current_test_info();
+  llvm::SmallString<128> name;
+  int fd;
+  llvm::sys::fs::createTemporaryFile(llvm::Twine(Info->test_case_name()) + "-" +
+                                         Info->name(),
+                                     "test", fd, name);
+
+  llvm::FileRemover remover(name);
+  ASSERT_GE(fd, 0);
+
+  File file(fd, File::eOpenOptionWrite, true);
+  ASSERT_TRUE(file.IsValid());
+
+  FILE *stream = file.GetStream();
+  ASSERT_TRUE(stream != NULL);
+
+  EXPECT_EQ(file.GetDescriptor(), fd);
+  EXPECT_EQ(file.GetWaitableHandle(), fd);
+}