Index: lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h =================================================================== --- lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -16,6 +16,7 @@ #include "lldb/lldb-forward.h" #include "lldb/Host/Pipe.h" +#include "lldb/Host/Terminal.h" #include "lldb/Utility/Connection.h" #include "lldb/Utility/IOObject.h" #include "lldb/Utility/Predicate.h" @@ -110,6 +111,7 @@ // BytesAvailable to disconnect, we won't try to read again. bool m_waiting_for_accept = false; bool m_child_processes_inherit; + TerminalState m_saved_term_state; std::string m_uri; Index: lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp =================================================================== --- lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -247,7 +247,9 @@ return eConnectionStatusError; } - if (::isatty(fd)) { + Terminal term{fd}; + if (term.IsATerminal()) { + m_saved_term_state.Save(term, false); // Set up serial terminal emulation struct termios options; ::tcgetattr(fd, &options); @@ -341,6 +343,9 @@ // Prevents reads and writes during shutdown. m_shutting_down = true; + m_saved_term_state.Restore(); + m_saved_term_state.Clear(); + Status error = m_read_sp->Close(); Status error2 = m_write_sp->Close(); if (error.Fail() || error2.Fail()) Index: lldb/test/API/functionalities/gdb_remote_client/TestPty.py =================================================================== --- lldb/test/API/functionalities/gdb_remote_client/TestPty.py +++ lldb/test/API/functionalities/gdb_remote_client/TestPty.py @@ -9,6 +9,16 @@ mydir = TestBase.compute_mydir(__file__) server_socket_class = PtyServerSocket + def setUp(self): + super().setUp() + import termios + self.orig_attr = termios.tcgetattr(self.server._socket._slave) + + def assert_attr_restored(self): + import termios + self.assertEqual(termios.tcgetattr(self.server._socket._slave), + self.orig_attr) + def test_process_connect_sync(self): """Test the process connect command in synchronous mode""" try: @@ -19,6 +29,7 @@ substrs=['Process', 'stopped']) finally: self.dbg.GetSelectedTarget().GetProcess().Kill() + self.assert_attr_restored() def test_process_connect_async(self): """Test the process connect command in asynchronous mode""" @@ -35,3 +46,4 @@ self.dbg.GetSelectedTarget().GetProcess().Kill() lldbutil.expect_state_changes(self, self.dbg.GetListener(), self.process(), [lldb.eStateExited]) + self.assert_attr_restored()