[Lldb-commits] [lldb] r212220 - Add host layer support for pipes.
Greg Clayton
gclayton at apple.com
Wed Jul 2 14:10:40 PDT 2014
Author: gclayton
Date: Wed Jul 2 16:10:39 2014
New Revision: 212220
URL: http://llvm.org/viewvc/llvm-project?rev=212220&view=rev
Log:
Add host layer support for pipes.
Windows does support pipes, but they do so in a slightly different way. Added a Host layer which abstracts the use of pipes into a new Pipe class that everyone can use.
Windows benefits include:
- Being able to interrupt running processes when IO is directly hooked up
- being able to interrupt long running python scripts
- being able to interrupt anything based on ConnectionFileDescriptor
Added:
lldb/trunk/include/lldb/Host/Pipe.h
lldb/trunk/source/Host/common/Pipe.cpp
Modified:
lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
lldb/trunk/source/Host/common/CMakeLists.txt
lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
lldb/trunk/source/Target/Process.cpp
Modified: lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h?rev=212220&r1=212219&r2=212220&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h (original)
+++ lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h Wed Jul 2 16:10:39 2014
@@ -24,6 +24,7 @@
// Project includes
#include "lldb/Core/Connection.h"
#include "lldb/Host/Mutex.h"
+#include "lldb/Host/Pipe.h"
#include "lldb/Host/Predicate.h"
namespace lldb_private {
@@ -122,8 +123,7 @@ protected:
FDType m_fd_recv_type;
std::unique_ptr<SocketAddress> m_udp_send_sockaddr;
uint32_t m_socket_timeout_usec;
- int m_pipe_read; // A pipe that we select on the reading end of along with
- int m_pipe_write; // m_fd_recv so we can force ourselves out of the select.
+ Pipe m_pipe;
Mutex m_mutex;
Predicate<uint16_t> m_port_predicate; // Used when binding to port zero to wait for the thread that creates the socket, binds and listens to resolve the port number
bool m_should_close_fd; // True if this class should close the file descriptor when it goes away.
Added: lldb/trunk/include/lldb/Host/Pipe.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Pipe.h?rev=212220&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Host/Pipe.h (added)
+++ lldb/trunk/include/lldb/Host/Pipe.h Wed Jul 2 16:10:39 2014
@@ -0,0 +1,83 @@
+//===-- Pipe.h --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Pipe_h_
+#define liblldb_Pipe_h_
+#if defined(__cplusplus)
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Pipe Pipe.h "lldb/Host/Pipe.h"
+/// @brief A class that abtracts unix style pipes.
+///
+/// A class that abstracts the LLDB core from host pipe functionality.
+//----------------------------------------------------------------------
+class Pipe
+{
+public:
+ static int kInvalidDescriptor;
+
+ Pipe();
+
+ ~Pipe();
+
+ bool
+ Open();
+
+ bool
+ IsValid() const;
+
+ bool
+ ReadDescriptorIsValid() const;
+
+ bool
+ WriteDescriptorIsValid() const;
+
+ int
+ GetReadFileDescriptor() const;
+
+ int
+ GetWriteFileDescriptor() const;
+
+ // Close both descriptors
+ void
+ Close();
+
+ bool
+ CloseReadFileDescriptor();
+
+ bool
+ CloseWriteFileDescriptor();
+
+ int
+ ReleaseReadFileDescriptor();
+
+ int
+ ReleaseWriteFileDescriptor();
+
+ size_t
+ Read (void *buf, size_t size);
+
+ size_t
+ Write (const void *buf, size_t size);
+private:
+ int m_fds[2];
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_Pipe_h_
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=212220&r1=212219&r2=212220&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Wed Jul 2 16:10:39 2014
@@ -83,6 +83,8 @@
2606EDDE184E68940034641B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 260C876910F538E700BB2B04 /* Foundation.framework */; };
2606EDDF184E68A10034641B /* liblldb-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2689FFCA13353D7A00698AC0 /* liblldb-core.a */; };
260A248E15D06C50009981B0 /* OptionValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 260A248D15D06C4F009981B0 /* OptionValues.h */; };
+ 260A39A619647A3A004B4130 /* Pipe.h in Headers */ = {isa = PBXBuildFile; fileRef = 260A39A519647A3A004B4130 /* Pipe.h */; };
+ 260A39A819647A4E004B4130 /* Pipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260A39A719647A4E004B4130 /* Pipe.cpp */; };
260A63171861008E00FECF8E /* IOHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 260A63161861008E00FECF8E /* IOHandler.h */; };
260A63191861009E00FECF8E /* IOHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260A63181861009E00FECF8E /* IOHandler.cpp */; };
260CC62E15D04377002BF2E0 /* OptionValueArgs.h in Headers */ = {isa = PBXBuildFile; fileRef = 260CC62115D04377002BF2E0 /* OptionValueArgs.h */; };
@@ -949,6 +951,8 @@
26022531115F27FA00A601A2 /* SBFileSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBFileSpec.h; path = include/lldb/API/SBFileSpec.h; sourceTree = "<group>"; };
26022532115F281400A601A2 /* SBFileSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBFileSpec.cpp; path = source/API/SBFileSpec.cpp; sourceTree = "<group>"; };
260A248D15D06C4F009981B0 /* OptionValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OptionValues.h; path = include/lldb/Interpreter/OptionValues.h; sourceTree = "<group>"; };
+ 260A39A519647A3A004B4130 /* Pipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Pipe.h; path = include/lldb/Host/Pipe.h; sourceTree = "<group>"; };
+ 260A39A719647A4E004B4130 /* Pipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Pipe.cpp; sourceTree = "<group>"; };
260A63111860FDB600FECF8E /* Queue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Queue.h; path = include/lldb/Target/Queue.h; sourceTree = "<group>"; };
260A63121860FDBD00FECF8E /* QueueItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = QueueItem.h; path = include/lldb/Target/QueueItem.h; sourceTree = "<group>"; };
260A63131860FDC700FECF8E /* QueueList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = QueueList.h; path = include/lldb/Target/QueueList.h; sourceTree = "<group>"; };
@@ -1228,6 +1232,7 @@
266DFE9613FD656E00D0C574 /* OperatingSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OperatingSystem.cpp; path = source/Target/OperatingSystem.cpp; sourceTree = "<group>"; };
266DFE9813FD658300D0C574 /* OperatingSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OperatingSystem.h; path = include/lldb/Target/OperatingSystem.h; sourceTree = "<group>"; };
266F5CBB12FC846200DFCE33 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Config.h; path = include/lldb/Host/Config.h; sourceTree = "<group>"; };
+ 26709E311964A34000B94724 /* LaunchServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LaunchServices.framework; path = ../../../../../../../System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework; sourceTree = "<group>"; };
2670F8111862B44A006B332C /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = /usr/lib/libncurses.dylib; sourceTree = "<absolute>"; };
2671A0CD134825F6003A87BB /* ConnectionMachPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConnectionMachPort.h; path = include/lldb/Core/ConnectionMachPort.h; sourceTree = "<group>"; };
2671A0CF13482601003A87BB /* ConnectionMachPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConnectionMachPort.cpp; path = source/Core/ConnectionMachPort.cpp; sourceTree = "<group>"; };
@@ -2161,6 +2166,7 @@
08FB7794FE84155DC02AAC07 /* lldb */ = {
isa = PBXGroup;
children = (
+ 26709E311964A34000B94724 /* LaunchServices.framework */,
26F5C32810F3DF7D009D5894 /* Libraries */,
264E8576159BE51A00E9D7A2 /* Resources */,
08FB7795FE84155DC02AAC07 /* Source */,
@@ -3422,6 +3428,7 @@
232CB611191E00CC00EF39FC /* NativeThreadProtocol.cpp */,
232CB612191E00CC00EF39FC /* NativeThreadProtocol.h */,
A36FF33D17D8E98800244D40 /* OptionParser.h */,
+ 260A39A519647A3A004B4130 /* Pipe.h */,
26BC7DD610F1B7D500F91463 /* Predicate.h */,
26D7E45B13D5E2F9007FD12B /* SocketAddress.h */,
26D7E45C13D5E30A007FD12B /* SocketAddress.cpp */,
@@ -3947,6 +3954,7 @@
69A01E1C1236C5D400C660B5 /* Host.cpp */,
69A01E1E1236C5D400C660B5 /* Mutex.cpp */,
A36FF33B17D8E94600244D40 /* OptionParser.cpp */,
+ 260A39A719647A4E004B4130 /* Pipe.cpp */,
69A01E1F1236C5D400C660B5 /* Symbols.cpp */,
268DA873130095ED00C9483A /* Terminal.cpp */,
69A01E201236C5D400C660B5 /* TimeValue.cpp */,
@@ -4190,6 +4198,7 @@
490A36C2180F0E9300BA31F8 /* PlatformWindows.h in Headers */,
26EFC4CE18CFAF0D00865D87 /* ObjectFileJIT.h in Headers */,
260CC63615D04377002BF2E0 /* OptionValueFormat.h in Headers */,
+ 260A39A619647A3A004B4130 /* Pipe.h in Headers */,
26D1804516CEE12500EDFB5B /* KQueue.h in Headers */,
260CC63715D04377002BF2E0 /* OptionValueSInt64.h in Headers */,
AF061F8C182C980000B6A19C /* HistoryUnwind.h in Headers */,
@@ -4845,6 +4854,7 @@
268900D313353E6F00698AC0 /* ClangExternalASTSourceCallbacks.cpp in Sources */,
268900D413353E6F00698AC0 /* ClangNamespaceDecl.cpp in Sources */,
268900D513353E6F00698AC0 /* CompileUnit.cpp in Sources */,
+ 260A39A819647A4E004B4130 /* Pipe.cpp in Sources */,
268900D613353E6F00698AC0 /* Declaration.cpp in Sources */,
268900D713353E6F00698AC0 /* DWARFCallFrameInfo.cpp in Sources */,
268900D813353E6F00698AC0 /* Function.cpp in Sources */,
@@ -5376,6 +5386,7 @@
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
+ "$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
);
FRAMEWORK_VERSION = A;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
@@ -5440,6 +5451,7 @@
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
+ "$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
);
FRAMEWORK_VERSION = A;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
@@ -5778,6 +5790,7 @@
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
+ "$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
);
FRAMEWORK_VERSION = A;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
@@ -6587,6 +6600,7 @@
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
+ "$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
);
FRAMEWORK_VERSION = A;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=212220&r1=212219&r2=212220&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Wed Jul 2 16:10:39 2014
@@ -97,9 +97,8 @@ ConnectionFileDescriptor::ConnectionFile
m_fd_send_type (eFDTypeFile),
m_fd_recv_type (eFDTypeFile),
m_udp_send_sockaddr (new SocketAddress()),
- m_socket_timeout_usec(0),
- m_pipe_read(-1),
- m_pipe_write(-1),
+ m_socket_timeout_usec (0),
+ m_pipe (),
m_mutex (Mutex::eMutexTypeRecursive),
m_should_close_fd (false),
m_shutting_down (false)
@@ -118,8 +117,7 @@ ConnectionFileDescriptor::ConnectionFile
m_fd_recv_type (eFDTypeFile),
m_udp_send_sockaddr (new SocketAddress()),
m_socket_timeout_usec(0),
- m_pipe_read(-1),
- m_pipe_write(-1),
+ m_pipe (),
m_mutex (Mutex::eMutexTypeRecursive),
m_should_close_fd (owns_fd),
m_shutting_down (false)
@@ -149,13 +147,7 @@ ConnectionFileDescriptor::OpenCommandPip
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
// Make the command file descriptor here:
- int filedes[2];
-#ifndef LLDB_DISABLE_POSIX
- int result = pipe (filedes);
-#else
- int result = -1;
-#endif
- if (result != 0)
+ if (!m_pipe.Open())
{
if (log)
log->Printf ("%p ConnectionFileDescriptor::OpenCommandPipe () - could not make pipe: %s",
@@ -163,12 +155,11 @@ ConnectionFileDescriptor::OpenCommandPip
}
else
{
- m_pipe_read = filedes[0];
- m_pipe_write = filedes[1];
if (log)
log->Printf ("%p ConnectionFileDescriptor::OpenCommandPipe() - success readfd=%d writefd=%d",
- static_cast<void*>(this), m_pipe_read,
- m_pipe_write);
+ static_cast<void*>(this),
+ m_pipe.GetReadFileDescriptor(),
+ m_pipe.GetWriteFileDescriptor());
}
}
@@ -180,25 +171,7 @@ ConnectionFileDescriptor::CloseCommandPi
log->Printf ("%p ConnectionFileDescriptor::CloseCommandPipe()",
static_cast<void*>(this));
- if (m_pipe_read != -1)
- {
-#ifdef _MSC_VER
- llvm_unreachable("pipe close unsupported in MSVC");
-#else
- close (m_pipe_read);
-#endif
- m_pipe_read = -1;
- }
-
- if (m_pipe_write != -1)
- {
-#ifdef _MSC_VER
- llvm_unreachable("pipe close unsupported in MSVC");
-#else
- close (m_pipe_write);
-#endif
- m_pipe_write = -1;
- }
+ m_pipe.Close();
}
bool
@@ -364,9 +337,7 @@ ConnectionFileDescriptor::Connect (const
bool
ConnectionFileDescriptor::InterruptRead()
{
- if (m_pipe_write != -1 )
- return write (m_pipe_write, "i", 1) == 1;
- return false;
+ return m_pipe.Write("i", 1) == 1;
}
ConnectionStatus
@@ -402,13 +373,13 @@ ConnectionFileDescriptor::Disconnect (Er
if (!got_lock)
{
- if (m_pipe_write != -1 )
+ if (m_pipe.WriteDescriptorIsValid())
{
int result;
- result = write (m_pipe_write, "q", 1);
+ result = m_pipe.Write("q", 1) == 1;
if (log)
log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, sent 'q' to %d, result = %d.",
- static_cast<void*>(this), m_pipe_write, result);
+ static_cast<void*>(this), m_pipe.GetWriteFileDescriptor(), result);
}
else if (log)
log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, but no command pipe is available.",
@@ -757,7 +728,7 @@ ConnectionFileDescriptor::BytesAvailable
// have another thread change these values out from under us
// and cause problems in the loop below where like in FS_SET()
const int data_fd = m_fd_recv;
- const int pipe_fd = m_pipe_read;
+ const int pipe_fd = m_pipe.GetReadFileDescriptor();
if (data_fd >= 0)
{
@@ -929,7 +900,7 @@ ConnectionFileDescriptor::BytesAvailable
// have another thread change these values out from under us
// and cause problems in the loop below where like in FS_SET()
const int data_fd = m_fd_recv;
- const int pipe_fd = m_pipe_read;
+ const int pipe_fd = m_pipe.GetReadFileDescriptor();
// Make sure the file descriptor can be used with select as it
// must be in range
Modified: lldb/trunk/source/Host/common/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/CMakeLists.txt?rev=212220&r1=212219&r2=212220&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/CMakeLists.txt (original)
+++ lldb/trunk/source/Host/common/CMakeLists.txt Wed Jul 2 16:10:39 2014
@@ -13,6 +13,7 @@ add_lldb_library(lldbHostCommon
NativeProcessProtocol.cpp
NativeThreadProtocol.cpp
OptionParser.cpp
+ Pipe.cpp
ProcessRunLock.cpp
SocketAddress.cpp
SoftwareBreakpoint.cpp
Added: lldb/trunk/source/Host/common/Pipe.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Pipe.cpp?rev=212220&view=auto
==============================================================================
--- lldb/trunk/source/Host/common/Pipe.cpp (added)
+++ lldb/trunk/source/Host/common/Pipe.cpp Wed Jul 2 16:10:39 2014
@@ -0,0 +1,172 @@
+//===-- Pipe.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/Pipe.h"
+
+#include <unistd.h>
+
+#ifdef _WIN32
+#include <io.h>
+#include <math.h> // TODO: not sure if this is needed for windows, remove if not
+#include <process.h>// TODO: not sure if this is needed for windows, remove if not
+#endif
+
+using namespace lldb_private;
+
+int Pipe::kInvalidDescriptor = -1;
+
+enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
+
+Pipe::Pipe()
+{
+ m_fds[READ] = Pipe::kInvalidDescriptor;
+ m_fds[WRITE] = Pipe::kInvalidDescriptor;
+}
+
+Pipe::~Pipe()
+{
+ Close();
+}
+
+bool
+Pipe::Open()
+{
+ if (IsValid())
+ return true;
+
+#ifdef _WIN32
+ if (::_pipe(m_fds, 256, O_BINARY) == 0)
+ return true
+#else
+ if (::pipe(m_fds) == 0)
+ return true;
+#endif
+ m_fds[READ] = Pipe::kInvalidDescriptor;
+ m_fds[WRITE] = Pipe::kInvalidDescriptor;
+ return false;
+}
+
+int
+Pipe::GetReadFileDescriptor() const
+{
+ return m_fds[READ];
+}
+
+int
+Pipe::GetWriteFileDescriptor() const
+{
+ return m_fds[WRITE];
+}
+
+int
+Pipe::ReleaseReadFileDescriptor()
+{
+ const int fd = m_fds[READ];
+ m_fds[READ] = Pipe::kInvalidDescriptor;
+ return fd;
+}
+
+int
+Pipe::ReleaseWriteFileDescriptor()
+{
+ const int fd = m_fds[WRITE];
+ m_fds[WRITE] = Pipe::kInvalidDescriptor;
+ return fd;
+}
+
+void
+Pipe::Close()
+{
+ CloseReadFileDescriptor();
+ CloseWriteFileDescriptor();
+}
+
+bool
+Pipe::ReadDescriptorIsValid() const
+{
+ return m_fds[READ] != Pipe::kInvalidDescriptor;
+}
+
+bool
+Pipe::WriteDescriptorIsValid() const
+{
+ return m_fds[WRITE] != Pipe::kInvalidDescriptor;
+}
+
+bool
+Pipe::IsValid() const
+{
+ return ReadDescriptorIsValid() && WriteDescriptorIsValid();
+}
+
+bool
+Pipe::CloseReadFileDescriptor()
+{
+ if (ReadDescriptorIsValid())
+ {
+ int err;
+#ifdef _WIN32
+ err = _close(m_fds[READ]);
+#else
+ err = close(m_fds[READ]);
+#endif
+ m_fds[READ] = Pipe::kInvalidDescriptor;
+ return err == 0;
+ }
+ return true;
+}
+
+bool
+Pipe::CloseWriteFileDescriptor()
+{
+ if (WriteDescriptorIsValid())
+ {
+ int err;
+#ifdef _WIN32
+ err = _close(m_fds[WRITE]);
+#else
+ err = close(m_fds[WRITE]);
+#endif
+ m_fds[WRITE] = Pipe::kInvalidDescriptor;
+ return err == 0;
+ }
+ return true;
+}
+
+
+size_t
+Pipe::Read (void *buf, size_t num_bytes)
+{
+ if (ReadDescriptorIsValid())
+ {
+ const int fd = GetReadFileDescriptor();
+#ifdef _WIN32
+ return _read (fd, (char *)buf, num_bytes);
+#else
+ return read (fd, buf, num_bytes);
+#endif
+ }
+ return 0; // Return 0 since errno won't be set if we didn't call read
+}
+
+size_t
+Pipe::Write (const void *buf, size_t num_bytes)
+{
+ if (WriteDescriptorIsValid())
+ {
+ const int fd = GetWriteFileDescriptor();
+#ifdef _WIN32
+ return _write (fd, (char *)buf, num_bytes);
+#else
+ return write (fd, buf, num_bytes);
+#endif
+ }
+ return 0; // Return 0 since errno won't be set if we didn't call write
+}
+
Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=212220&r1=212219&r2=212220&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Wed Jul 2 16:10:39 2014
@@ -32,6 +32,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/Pipe.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/PythonDataObjects.h"
@@ -580,8 +581,7 @@ ScriptInterpreterPython::ExecuteOneLine
StreamFileSP output_file_sp;
StreamFileSP error_file_sp;
Communication output_comm ("lldb.ScriptInterpreterPython.ExecuteOneLine.comm");
- int pipe_fds[2] = { -1, -1 };
-
+ bool join_read_thread = false;
if (options.GetEnableIO())
{
if (result)
@@ -589,21 +589,17 @@ ScriptInterpreterPython::ExecuteOneLine
input_file_sp = debugger.GetInputFile();
// Set output to a temporary file so we can forward the results on to the result object
-#ifdef _MSC_VER
- // pipe is not supported on windows so default to a fail condition
- int err = 1;
-#else
- int err = pipe(pipe_fds);
-#endif
- if (err == 0)
+ Pipe pipe;
+ if (pipe.Open())
{
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe_fds[0], true));
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(), true));
if (conn_ap->IsConnected())
{
output_comm.SetConnection(conn_ap.release());
output_comm.SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived, &result->GetOutputStream());
output_comm.StartReadThread();
- FILE *outfile_handle = fdopen (pipe_fds[1], "w");
+ join_read_thread = true;
+ FILE *outfile_handle = fdopen (pipe.ReleaseWriteFileDescriptor(), "w");
output_file_sp.reset(new StreamFile(outfile_handle, true));
error_file_sp = output_file_sp;
if (outfile_handle)
@@ -672,7 +668,7 @@ ScriptInterpreterPython::ExecuteOneLine
if (out_file != err_file)
::fflush (err_file);
- if (pipe_fds[0] != -1)
+ if (join_read_thread)
{
// Close the write end of the pipe since we are done with our
// one line script. This should cause the read thread that
Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=212220&r1=212219&r2=212220&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Wed Jul 2 16:10:39 2014
@@ -27,6 +27,7 @@
#include "lldb/Expression/ClangUserExpression.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/Pipe.h"
#include "lldb/Host/Terminal.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
@@ -4442,8 +4443,7 @@ public:
m_process (process),
m_read_file (),
m_write_file (write_fd, false),
- m_pipe_read(),
- m_pipe_write()
+ m_pipe ()
{
m_read_file.SetDescriptor(GetInputFD(), false);
}
@@ -4457,30 +4457,15 @@ public:
bool
OpenPipes ()
{
- if (m_pipe_read.IsValid() && m_pipe_write.IsValid())
+ if (m_pipe.IsValid())
return true;
-
- int fds[2];
-#ifdef _WIN32
- // pipe is not supported on windows so default to a fail condition
- int err = 1;
-#else
- int err = pipe(fds);
-#endif
- if (err == 0)
- {
- m_pipe_read.SetDescriptor(fds[0], true);
- m_pipe_write.SetDescriptor(fds[1], true);
- return true;
- }
- return false;
+ return m_pipe.Open();
}
void
ClosePipes()
{
- m_pipe_read.Close();
- m_pipe_write.Close();
+ m_pipe.Close();
}
// Each IOHandler gets to run until it is done. It should read data
@@ -4495,7 +4480,7 @@ public:
if (OpenPipes())
{
const int read_fd = m_read_file.GetDescriptor();
- const int pipe_read_fd = m_pipe_read.GetDescriptor();
+ const int pipe_read_fd = m_pipe.GetReadFileDescriptor();
TerminalState terminal_state;
terminal_state.Save (read_fd, false);
Terminal terminal(read_fd);
@@ -4536,17 +4521,18 @@ public:
if (FD_ISSET (pipe_read_fd, &read_fdset))
{
// Consume the interrupt byte
- n = 1;
- m_pipe_read.Read (&ch, n);
- switch (ch)
+ if (m_pipe.Read (&ch, 1) == 1)
{
- case 'q':
- SetIsDone(true);
- break;
- case 'i':
- if (StateIsRunningState(m_process->GetState()))
- m_process->Halt();
- break;
+ switch (ch)
+ {
+ case 'q':
+ SetIsDone(true);
+ break;
+ case 'i':
+ if (StateIsRunningState(m_process->GetState()))
+ m_process->Halt();
+ break;
+ }
}
}
}
@@ -4582,30 +4568,20 @@ public:
virtual void
Cancel ()
{
- size_t n = 1;
char ch = 'q'; // Send 'q' for quit
- m_pipe_write.Write (&ch, n);
+ m_pipe.Write (&ch, 1);
}
virtual bool
Interrupt ()
{
-#ifdef _MSC_VER
- // Windows doesn't support pipes, so we will send an async interrupt
- // event to stop the process
- if (StateIsRunningState(m_process->GetState()))
- m_process->SendAsyncInterrupt();
-#else
// Do only things that are safe to do in an interrupt context (like in
// a SIGINT handler), like write 1 byte to a file descriptor. This will
// interrupt the IOHandlerProcessSTDIO::Run() and we can look at the byte
// that was written to the pipe and then call m_process->Halt() from a
// much safer location in code.
- size_t n = 1;
char ch = 'i'; // Send 'i' for interrupt
- m_pipe_write.Write (&ch, n);
-#endif
- return true;
+ return m_pipe.Write (&ch, 1) == 1;
}
virtual void
@@ -4618,9 +4594,7 @@ protected:
Process *m_process;
File m_read_file; // Read from this file (usually actual STDIN for LLDB
File m_write_file; // Write to this file (usually the master pty for getting io to debuggee)
- File m_pipe_read;
- File m_pipe_write;
-
+ Pipe m_pipe;
};
void
More information about the lldb-commits
mailing list