summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2012-11-30 20:23:19 +0000
committerJim Ingham <jingham@apple.com>2012-11-30 20:23:19 +0000
commitc5917d9a38ce0e4ad0a8f888f759de382dbe8f2d (patch)
tree4adecd07d2319ceb7d1d5028fc69f5244ad287b5
parent69ea91b4028711040aeb4bf46efa95214f693e15 (diff)
downloadbcm5719-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.h8
-rw-r--r--lldb/include/lldb/Core/Debugger.h7
-rw-r--r--lldb/include/lldb/Host/Terminal.h3
-rw-r--r--lldb/source/API/SBDebugger.cpp14
-rw-r--r--lldb/source/Core/Debugger.cpp21
-rw-r--r--lldb/source/Host/common/Terminal.cpp9
-rw-r--r--lldb/tools/driver/Driver.cpp20
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.
OpenPOWER on IntegriCloud