[Lldb-commits] [lldb] a182b4b - [lldb][windows] fix command source hitting EOF (#194950)

via lldb-commits lldb-commits at lists.llvm.org
Fri May 29 05:47:27 PDT 2026


Author: Charles Zablit
Date: 2026-05-29T13:47:20+01:00
New Revision: a182b4bed2c443f383258fe7dcd886b39624526f

URL: https://github.com/llvm/llvm-project/commit/a182b4bed2c443f383258fe7dcd886b39624526f
DIFF: https://github.com/llvm/llvm-project/commit/a182b4bed2c443f383258fe7dcd886b39624526f.diff

LOG: [lldb][windows] fix command source hitting EOF (#194950)

Added: 
    

Modified: 
    lldb/include/lldb/Host/FileBase.h
    lldb/include/lldb/Host/windows/FileWindows.h
    lldb/source/Host/common/File.cpp
    lldb/source/Host/windows/FileWindows.cpp
    lldb/test/API/python_api/file_handle/TestFileHandle.py

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Host/FileBase.h b/lldb/include/lldb/Host/FileBase.h
index 62773de1e0273..54ca89f3201c6 100644
--- a/lldb/include/lldb/Host/FileBase.h
+++ b/lldb/include/lldb/Host/FileBase.h
@@ -374,6 +374,9 @@ class File : public IOObject {
   /// appropriate platform-specific terminal probing.
   virtual void CalculateInteractiveAndTerminal();
 
+  /// Called after a stream is successfully opened from a descriptor.
+  virtual void OnStreamOpened() {}
+
 private:
   File(const File &) = delete;
   const File &operator=(const File &) = delete;

diff  --git a/lldb/include/lldb/Host/windows/FileWindows.h b/lldb/include/lldb/Host/windows/FileWindows.h
index a704e7e508684..b7a4981553ac8 100644
--- a/lldb/include/lldb/Host/windows/FileWindows.h
+++ b/lldb/include/lldb/Host/windows/FileWindows.h
@@ -48,6 +48,8 @@ class NativeFileWindows : public NativeFileBase {
   bool TryWriteStreamUnlocked(const void *buf, size_t &num_bytes,
                               Status &error) override;
 
+  void OnStreamOpened() override;
+
 private:
   /// Set when this file wraps stdin/stdout/stderr connected to a console;
   /// triggers the raw_fd_ostream path for correct non-ASCII output.

diff  --git a/lldb/source/Host/common/File.cpp b/lldb/source/Host/common/File.cpp
index 07a1377133a32..499df4e542ab2 100644
--- a/lldb/source/Host/common/File.cpp
+++ b/lldb/source/Host/common/File.cpp
@@ -21,6 +21,7 @@
 #include "lldb/Host/Host.h"
 #include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/VASPrintf.h"
 #include "llvm/ADT/StringExtras.h"
@@ -264,32 +265,38 @@ IOObject::WaitableHandle NativeFileBase::GetWaitableHandle() {
 
 FILE *NativeFileBase::GetStream() {
   ValueGuard stream_guard = StreamIsValid();
-  if (!stream_guard) {
-    if (ValueGuard descriptor_guard = DescriptorIsValid()) {
-      auto mode = GetStreamOpenModeFromOptions(m_options);
-      if (!mode)
-        llvm::consumeError(mode.takeError());
-      else {
-        if (!m_own_descriptor) {
-          // We must duplicate the file descriptor if we don't own it because
-          // when you call fdopen, the stream will own the fd.
-          m_descriptor = Dup(m_descriptor);
-          m_own_descriptor = true;
-        }
-
-        m_stream = llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor,
-                                               mode.get());
-
-        // If we got a stream, then we own the stream and should no longer own
-        // the descriptor because fclose() will close it for us
-
-        if (m_stream) {
-          m_own_stream = true;
-          m_own_descriptor = false;
-        }
-      }
-    }
+  if (stream_guard)
+    return m_stream;
+
+  ValueGuard descriptor_guard = DescriptorIsValid();
+  if (!descriptor_guard)
+    return m_stream;
+
+  auto mode_or_err = GetStreamOpenModeFromOptions(m_options);
+  if (!mode_or_err) {
+    LLDB_LOG_ERROR(GetLog(LLDBLog::Object), mode_or_err.takeError(),
+                   "Failed to get stream options: {0}");
+    return m_stream;
+  }
+  const char *mode = *mode_or_err;
+
+  if (!m_own_descriptor) {
+    // We must duplicate the file descriptor if we don't own it because
+    // when you call fdopen, the stream will own the fd.
+    m_descriptor = Dup(m_descriptor);
+    m_own_descriptor = true;
   }
+
+  m_stream = llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, mode);
+
+  // If we got a stream, then we own the stream and should no longer own
+  // the descriptor because fclose() will close it for us.
+  if (m_stream) {
+    m_own_stream = true;
+    m_own_descriptor = false;
+    OnStreamOpened();
+  }
+
   return m_stream;
 }
 

diff  --git a/lldb/source/Host/windows/FileWindows.cpp b/lldb/source/Host/windows/FileWindows.cpp
index 2058424d6c841..fc60c1815b066 100644
--- a/lldb/source/Host/windows/FileWindows.cpp
+++ b/lldb/source/Host/windows/FileWindows.cpp
@@ -143,4 +143,9 @@ Status NativeFileWindows::Write(const void *buf, size_t &num_bytes,
   return error;
 }
 
+void NativeFileWindows::OnStreamOpened() {
+  if ((m_options & OpenOptionsModeMask) == eOpenOptionReadOnly)
+    setvbuf(m_stream, nullptr, _IONBF, 0);
+}
+
 char NativeFileWindows::ID = 0;

diff  --git a/lldb/test/API/python_api/file_handle/TestFileHandle.py b/lldb/test/API/python_api/file_handle/TestFileHandle.py
index a0e66199d3f54..1c93282a265e5 100644
--- a/lldb/test/API/python_api/file_handle/TestFileHandle.py
+++ b/lldb/test/API/python_api/file_handle/TestFileHandle.py
@@ -679,7 +679,6 @@ def test_stdout_file(self):
             lines = [x for x in f.read().strip().split() if x != "7"]
             self.assertEqual(lines, ["foobar"])
 
-    @skipIf(hostoslist=["windows"])
     def test_stdout_file_interactive(self):
         """Ensure when we read stdin from a file, outputs from python goes to the right I/O stream."""
         with open(self.in_filename, "w") as f:


        


More information about the lldb-commits mailing list