summaryrefslogtreecommitdiff
path: root/tools/lldb-mi/MICmnStreamStdinLinux.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lldb-mi/MICmnStreamStdinLinux.cpp')
-rw-r--r--tools/lldb-mi/MICmnStreamStdinLinux.cpp307
1 files changed, 160 insertions, 147 deletions
diff --git a/tools/lldb-mi/MICmnStreamStdinLinux.cpp b/tools/lldb-mi/MICmnStreamStdinLinux.cpp
index f73dc32d8258..07e652d84c19 100644
--- a/tools/lldb-mi/MICmnStreamStdinLinux.cpp
+++ b/tools/lldb-mi/MICmnStreamStdinLinux.cpp
@@ -8,22 +8,22 @@
//===----------------------------------------------------------------------===//
//++
-// File: MIUtilStreamStdin.cpp
+// File: MIUtilStreamStdin.cpp
//
-// Overview: CMICmnStreamStdinLinux implementation.
+// Overview: CMICmnStreamStdinLinux implementation.
//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
//
-// Copyright: None.
+// Copyright: None.
//--
// Third Party Headers:
-#if !defined( _MSC_VER )
+#if defined(__APPLE__)
#include <sys/select.h>
-#include <termios.h>
-#endif // !defined( _MSC_VER )
+#include <unistd.h> // For STDIN_FILENO
+#endif // defined( __APPLE__ )
#include <string.h> // For std::strerror()
// In-house headers:
@@ -33,180 +33,193 @@
#include "MIUtilSingletonHelper.h"
//++ ------------------------------------------------------------------------------------
-// Details: CMICmnStreamStdinLinux constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
+// Details: CMICmnStreamStdinLinux constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
//--
-CMICmnStreamStdinLinux::CMICmnStreamStdinLinux( void )
-: m_constBufferSize( 1024 )
-, m_pStdin( nullptr )
-, m_pCmdBuffer( nullptr )
+CMICmnStreamStdinLinux::CMICmnStreamStdinLinux(void)
+ : m_constBufferSize(1024)
+ , m_pStdin(nullptr)
+ , m_pCmdBuffer(nullptr)
{
}
//++ ------------------------------------------------------------------------------------
-// Details: CMICmnStreamStdinLinux destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
+// Details: CMICmnStreamStdinLinux destructor.
+// Type: Overridable.
+// Args: None.
+// Return: None.
+// Throws: None.
//--
-CMICmnStreamStdinLinux::~CMICmnStreamStdinLinux( void )
+CMICmnStreamStdinLinux::~CMICmnStreamStdinLinux(void)
{
- Shutdown();
+ Shutdown();
}
//++ ------------------------------------------------------------------------------------
-// Details: Initialize resources for *this Stdin stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
+// Details: Initialize resources for *this Stdin stream.
+// Type: Method.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
//--
-bool CMICmnStreamStdinLinux::Initialize( void )
+bool
+CMICmnStreamStdinLinux::Initialize(void)
{
- if( m_bInitialized )
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Note initialisation order is important here as some resources depend on previous
- MI::ModuleInit< CMICmnLog > ( IDS_MI_INIT_ERR_LOG , bOk, errMsg );
- MI::ModuleInit< CMICmnResources >( IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg );
-
- // Other resources required
- if( bOk )
- {
- m_pCmdBuffer = new MIchar[ m_constBufferSize ];
- m_pStdin = stdin;
- }
-
- // Clear error indicators for std input
- ::clearerr( stdin );
-
- m_bInitialized = bOk;
-
- if( !bOk )
- {
- CMIUtilString strInitError( CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_OS_STDIN_HANDLER ), errMsg.c_str() ) );
- SetErrorDescription( strInitError );
- return MIstatus::failure;
- }
-
- return MIstatus::success;
+ if (m_bInitialized)
+ return MIstatus::success;
+
+ bool bOk = MIstatus::success;
+ CMIUtilString errMsg;
+
+ // Note initialisation order is important here as some resources depend on previous
+ MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
+ MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
+
+ // Other resources required
+ if (bOk)
+ {
+ m_pCmdBuffer = new MIchar[m_constBufferSize];
+ m_pStdin = stdin;
+ }
+
+ // Clear error indicators for std input
+ ::clearerr(stdin);
+
+ m_bInitialized = bOk;
+
+ if (!bOk)
+ {
+ CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_OS_STDIN_HANDLER), errMsg.c_str()));
+ SetErrorDescription(strInitError);
+ return MIstatus::failure;
+ }
+
+ return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
-// Details: Release resources for *this Stdin stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
+// Details: Release resources for *this Stdin stream.
+// Type: Method.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
//--
-bool CMICmnStreamStdinLinux::Shutdown( void )
+bool
+CMICmnStreamStdinLinux::Shutdown(void)
{
- if( !m_bInitialized )
- return MIstatus::success;
+ if (!m_bInitialized)
+ return MIstatus::success;
- m_bInitialized = false;
+ m_bInitialized = false;
- ClrErrorDescription();
+ ClrErrorDescription();
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
+ bool bOk = MIstatus::success;
+ CMIUtilString errMsg;
- // Tidy up
- if( m_pCmdBuffer != nullptr )
- {
- delete [] m_pCmdBuffer;
- m_pCmdBuffer = nullptr;
- }
- m_pStdin = nullptr;
+ // Tidy up
+ if (m_pCmdBuffer != nullptr)
+ {
+ delete[] m_pCmdBuffer;
+ m_pCmdBuffer = nullptr;
+ }
+ m_pStdin = nullptr;
- // Note shutdown order is important here
- MI::ModuleShutdown< CMICmnResources >( IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg );
- MI::ModuleShutdown< CMICmnLog > ( IDS_MI_INIT_ERR_LOG , bOk, errMsg );
+ // Note shutdown order is important here
+ MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
+ MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
- if( !bOk )
- {
- SetErrorDescriptionn( MIRSRC( IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER ), errMsg.c_str() );
- }
+ if (!bOk)
+ {
+ SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER), errMsg.c_str());
+ }
- return MIstatus::success;
-}
+ return MIstatus::success;
+}
//++ ------------------------------------------------------------------------------------
-// Details: Determine if stdin has any characters present in its buffer.
-// Type: Method.
-// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
+// Details: Determine if stdin has any characters present in its buffer.
+// Type: Method.
+// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
//--
-bool CMICmnStreamStdinLinux::InputAvailable( bool & vwbAvail )
+bool
+CMICmnStreamStdinLinux::InputAvailable(bool &vwbAvail)
{
-/* AD: Not used ATM but could come in handy just in case we need to do
- this, poll for input
-
- static const int STDIN = 0;
- static bool bInitialized = false;
-
- if( !bInitialized )
- {
- // Use termios to turn off line buffering
- ::termios term;
- ::tcgetattr( STDIN, &term );
- ::term.c_lflag &= ~ICANON;
- ::tcsetattr( STDIN, TCSANOW, &term );
- ::setbuf( stdin, NULL );
- bInitialized = true;
+#if defined(__APPLE__)
+ // The code below is needed on OSX where lldb-mi hangs when doing -exec-run.
+ // The hang seems to come from calling fgets and fileno from different thread.
+ // Although this problem was not observed on Linux.
+ // A solution based on 'ioctl' was initially committed but it seems to make
+ // lldb-mi takes much more processor time. The solution based on 'select' works
+ // well but it seems to slow the execution of lldb-mi tests a lot on Linux.
+ // As a result, this code is #defined to run only on OSX.
+ fd_set setOfStdin;
+ FD_ZERO(&setOfStdin);
+ FD_SET(STDIN_FILENO, &setOfStdin);
+
+ // Wait while input would be available
+ if (::select(STDIN_FILENO + 1, &setOfStdin, nullptr, nullptr, nullptr) == -1)
+ {
+ vwbAvail = false;
+ return MIstatus::failure;
}
- int nBytesWaiting;
- ::ioctl( STDIN, FIONREAD, &nBytesWaiting );
- vwbAvail = (nBytesWaiting > 0);
-
- return MIstatus::success;
-*/
-
- return MIstatus::success;
+#endif // defined( __APPLE__ )
+ vwbAvail = true;
+ return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
-// Details: Wait on new line of data from stdin stream (completed by '\n' or '\r').
-// Type: Method.
-// Args: vwErrMsg - (W) Empty string ok or error description.
-// Return: MIchar * - text buffer pointer or NULL on failure.
-// Throws: None.
+// Details: Wait on new line of data from stdin stream (completed by '\n' or '\r').
+// Type: Method.
+// Args: vwErrMsg - (W) Empty string ok or error description.
+// Return: MIchar * - text buffer pointer or NULL on failure.
+// Throws: None.
//--
-const MIchar * CMICmnStreamStdinLinux::ReadLine( CMIUtilString & vwErrMsg )
+const MIchar *
+CMICmnStreamStdinLinux::ReadLine(CMIUtilString &vwErrMsg)
{
- vwErrMsg.clear();
-
- // Read user input
- const MIchar * pText = ::fgets( &m_pCmdBuffer[ 0 ], m_constBufferSize, stdin );
- if( pText == nullptr )
- {
- if( ::ferror( m_pStdin ) != 0 )
- vwErrMsg = ::strerror( errno );
- return nullptr;
- }
+ vwErrMsg.clear();
+
+ // Read user input
+ const MIchar *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
+ if (pText == nullptr)
+ {
+ if (::ferror(m_pStdin) != 0)
+ vwErrMsg = ::strerror(errno);
+ return nullptr;
+ }
// Strip off new line characters
- for( MIchar * pI = m_pCmdBuffer; *pI != '\0'; pI++ )
- {
- if( (*pI == '\n') || (*pI == '\r') )
- {
- *pI = '\0';
- break;
- }
- }
-
- return pText;
+ for (MIchar *pI = m_pCmdBuffer; *pI != '\0'; pI++)
+ {
+ if ((*pI == '\n') || (*pI == '\r'))
+ {
+ *pI = '\0';
+ break;
+ }
+ }
+
+ return pText;
}
+//++ ------------------------------------------------------------------------------------
+// Details: Interrupt current and prevent new ReadLine operations.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+void
+CMICmnStreamStdinLinux::InterruptReadLine(void)
+{
+ fclose(stdin);
+}