diff options
author | Jim Ingham <jingham@apple.com> | 2012-11-30 20:23:19 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2012-11-30 20:23:19 +0000 |
commit | c5917d9a38ce0e4ad0a8f888f759de382dbe8f2d (patch) | |
tree | 4adecd07d2319ceb7d1d5028fc69f5244ad287b5 | |
parent | 69ea91b4028711040aeb4bf46efa95214f693e15 (diff) | |
download | bcm5719-llvm-c5917d9a38ce0e4ad0a8f888f759de382dbe8f2d.tar.gz bcm5719-llvm-c5917d9a38ce0e4ad0a8f888f759de382dbe8f2d.zip |
Save and restore terminal state when lldb is suspended with SIGTSTP and resumed with SIGCONT.
Readline & gdb have a bunch of code to handle older UNIX'es with other job control mechanisms.
I didn't try to replicate that.
llvm-svn: 169032
-rw-r--r-- | lldb/include/lldb/API/SBDebugger.h | 8 | ||||
-rw-r--r-- | lldb/include/lldb/Core/Debugger.h | 7 | ||||
-rw-r--r-- | lldb/include/lldb/Host/Terminal.h | 3 | ||||
-rw-r--r-- | lldb/source/API/SBDebugger.cpp | 14 | ||||
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 21 | ||||
-rw-r--r-- | lldb/source/Host/common/Terminal.cpp | 9 | ||||
-rw-r--r-- | lldb/tools/driver/Driver.cpp | 20 |
7 files changed, 80 insertions, 2 deletions
diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 41bcfa5068c..2de86d6a8ca 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -78,7 +78,7 @@ public: void SetErrorFileHandle (FILE *f, bool transfer_ownership); - + FILE * GetInputFileHandle (); @@ -88,6 +88,12 @@ public: FILE * GetErrorFileHandle (); + void + SaveInputTerminalState(); + + void + RestoreInputTerminalState(); + lldb::SBCommandInterpreter GetCommandInterpreter (); diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 67fa370caaa..f47153b00c8 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -116,6 +116,12 @@ public: void SetErrorFileHandle (FILE *fh, bool tranfer_ownership); + + void + SaveInputTerminalState(); + + void + RestoreInputTerminalState(); Stream& GetOutputStream () @@ -351,6 +357,7 @@ protected: StreamFile m_input_file; StreamFile m_output_file; StreamFile m_error_file; + TerminalState m_terminal_state; TargetList m_target_list; PlatformList m_platform_list; Listener m_listener; diff --git a/lldb/include/lldb/Host/Terminal.h b/lldb/include/lldb/Host/Terminal.h index dfa345182d7..201f07a8a5e 100644 --- a/lldb/include/lldb/Host/Terminal.h +++ b/lldb/include/lldb/Host/Terminal.h @@ -132,6 +132,9 @@ public: //------------------------------------------------------------------ bool IsValid() const; + + void + Clear (); protected: diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index af9447a7e18..0c957a677df 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -291,6 +291,20 @@ SBDebugger::GetErrorFileHandle () return NULL; } +void +SBDebugger::SaveInputTerminalState() +{ + if (m_opaque_sp) + m_opaque_sp->SaveInputTerminalState(); +} + +void +SBDebugger::RestoreInputTerminalState() +{ + if (m_opaque_sp) + m_opaque_sp->RestoreInputTerminalState(); + +} SBCommandInterpreter SBDebugger::GetCommandInterpreter () { diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index aadbf4d1da3..e817868eb7b 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -548,6 +548,7 @@ Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) : m_input_file (), m_output_file (), m_error_file (), + m_terminal_state (), m_target_list (*this), m_platform_list (), m_listener ("lldb.Debugger"), @@ -615,6 +616,7 @@ Debugger::Clear() // Close the input file _before_ we close the input read communications class // as it does NOT own the input file, our m_input_file does. + m_terminal_state.Clear(); GetInputFile().Close (); // Now that we have closed m_input_file, we can now tell our input communication // class to close down. Its read thread should quickly exit after we close @@ -662,7 +664,10 @@ Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) // want to objects trying to own and close a file descriptor. m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false)); m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this); - + + // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. + SaveInputTerminalState (); + Error error; if (m_input_comm.StartReadThread (&error) == false) { @@ -698,6 +703,20 @@ Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) err_file.SetStream (stderr, false); } +void +Debugger::SaveInputTerminalState () +{ + File &in_file = GetInputFile(); + if (in_file.GetDescriptor() != File::kInvalidDescriptor) + m_terminal_state.Save(in_file.GetDescriptor(), true); +} + +void +Debugger::RestoreInputTerminalState () +{ + m_terminal_state.Restore(); +} + ExecutionContext Debugger::GetSelectedExecutionContext () { diff --git a/lldb/source/Host/common/Terminal.cpp b/lldb/source/Host/common/Terminal.cpp index ce0e15fb610..89d21cf0bf6 100644 --- a/lldb/source/Host/common/Terminal.cpp +++ b/lldb/source/Host/common/Terminal.cpp @@ -120,6 +120,15 @@ TerminalState::~TerminalState() { } +void +TerminalState::Clear () +{ + m_tty.Clear(); + m_tflags = -1; + m_termios_ap.reset(); + m_process_group = -1; +} + //---------------------------------------------------------------------- // Save the current state of the TTY for the file descriptor "fd" // and if "save_process_group" is true, attempt to save the process diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 85fec519f37..b410f572a6e 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -1579,6 +1579,24 @@ sigint_handler (int signo) exit (signo); } +void +sigtstp_handler (int signo) +{ + g_driver->GetDebugger().SaveInputTerminalState(); + signal (signo, SIG_DFL); + kill (getpid(), signo); + signal (signo, sigtstp_handler); +} + +void +sigcont_handler (int signo) +{ + g_driver->GetDebugger().RestoreInputTerminalState(); + signal (signo, SIG_DFL); + kill (getpid(), signo); + signal (signo, sigcont_handler); +} + int main (int argc, char const *argv[], const char *envp[]) { @@ -1589,6 +1607,8 @@ main (int argc, char const *argv[], const char *envp[]) signal (SIGPIPE, SIG_IGN); signal (SIGWINCH, sigwinch_handler); signal (SIGINT, sigint_handler); + signal (SIGTSTP, sigtstp_handler); + signal (SIGCONT, sigcont_handler); // Create a scope for driver so that the driver object will destroy itself // before SBDebugger::Terminate() is called. |