ovyalov created this revision.
ovyalov added a reviewer: clayborg.
ovyalov added a subscriber: lldb-commits.
Herald added subscribers: srhines, danalbert, tberghammer.
Make Socket to support plugin interface - moved implementation classes into
source/Plugins/Socket folder and migrated most of use cases in order to rely on
base Socket class.
http://reviews.llvm.org/D14085
Files:
cmake/LLDBDependencies.cmake
include/lldb/Core/PluginManager.h
include/lldb/Host/Socket.h
include/lldb/Host/common/TCPSocket.h
include/lldb/Host/common/UDPSocket.h
include/lldb/Host/linux/AbstractSocket.h
include/lldb/Host/posix/DomainSocket.h
include/lldb/lldb-forward.h
include/lldb/lldb-private-interfaces.h
lldb.xcodeproj/project.pbxproj
source/Core/PluginManager.cpp
source/Host/CMakeLists.txt
source/Host/common/Socket.cpp
source/Host/common/TCPSocket.cpp
source/Host/common/UDPSocket.cpp
source/Host/linux/AbstractSocket.cpp
source/Host/posix/ConnectionFileDescriptorPosix.cpp
source/Host/posix/DomainSocket.cpp
source/Initialization/SystemInitializerCommon.cpp
source/Plugins/CMakeLists.txt
source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
source/Plugins/Socket/CMakeLists.txt
source/Plugins/Socket/Linux/AbstractSocket.cpp
source/Plugins/Socket/Linux/AbstractSocket.h
source/Plugins/Socket/Linux/CMakeLists.txt
source/Plugins/Socket/POSIX/CMakeLists.txt
source/Plugins/Socket/POSIX/DomainSocket.cpp
source/Plugins/Socket/POSIX/DomainSocket.h
source/Plugins/Socket/TCP/CMakeLists.txt
source/Plugins/Socket/TCP/TCPSocket.cpp
source/Plugins/Socket/TCP/TCPSocket.h
source/Plugins/Socket/UDP/CMakeLists.txt
source/Plugins/Socket/UDP/UDPSocket.cpp
source/Plugins/Socket/UDP/UDPSocket.h
tools/lldb-server/Acceptor.cpp
tools/lldb-server/lldb-platform.cpp
unittests/Host/SocketTest.cpp
Index: unittests/Host/SocketTest.cpp
===================================================================
--- unittests/Host/SocketTest.cpp
+++ unittests/Host/SocketTest.cpp
@@ -21,12 +21,8 @@
#include "lldb/Host/Config.h"
#include "lldb/Host/Socket.h"
-#include "lldb/Host/common/TCPSocket.h"
-#include "lldb/Host/common/UDPSocket.h"
-#ifndef LLDB_DISABLE_POSIX
-#include "lldb/Host/posix/DomainSocket.h"
-#endif
+#include "Plugins/Socket/UDP/UDPSocket.h"
using namespace lldb_private;
@@ -40,6 +36,7 @@
WSADATA data;
::WSAStartup(MAKEWORD(2, 2), &data);
#endif
+ Socket::Initialize();
}
void
@@ -58,13 +55,12 @@
*error = listen_socket->Accept(listen_remote_address, child_processes_inherit, *accept_socket);
}
- template<typename SocketType>
void
- CreateConnectedSockets(const char *listen_remote_address, const std::function<std::string(const SocketType&)> &get_connect_addr, std::unique_ptr<SocketType> *a_up, std::unique_ptr<SocketType> *b_up)
+ CreateConnectedSockets(const char* scheme, const char *listen_remote_address, const std::function<std::string(const Socket&)> &get_connect_addr, std::unique_ptr<Socket> *a_up, std::unique_ptr<Socket> *b_up)
{
bool child_processes_inherit = false;
Error error;
- std::unique_ptr<SocketType> listen_socket_up(new SocketType(child_processes_inherit, error));
+ std::unique_ptr<Socket> listen_socket_up(Socket::Create(scheme, child_processes_inherit, error));
EXPECT_FALSE(error.Fail());
error = listen_socket_up->Listen(listen_remote_address, 5);
EXPECT_FALSE(error.Fail());
@@ -76,7 +72,7 @@
&accept_socket, &accept_error);
std::string connect_remote_address = get_connect_addr(*listen_socket_up);
- std::unique_ptr<SocketType> connect_socket_up(new SocketType(child_processes_inherit, error));
+ std::unique_ptr<Socket> connect_socket_up(Socket::Create(scheme, child_processes_inherit, error));
EXPECT_FALSE(error.Fail());
error = connect_socket_up->Connect(connect_remote_address.c_str());
EXPECT_FALSE(error.Fail());
@@ -88,7 +84,7 @@
EXPECT_TRUE((*a_up)->IsValid());
accept_thread.join();
- b_up->reset(static_cast<SocketType*>(accept_socket));
+ b_up->reset(accept_socket);
EXPECT_TRUE(accept_error.Success());
EXPECT_NE(nullptr, b_up->get());
EXPECT_TRUE((*b_up)->IsValid());
@@ -138,44 +134,47 @@
const std::string file_name(file_name_str);
free(file_name_str);
- std::unique_ptr<DomainSocket> socket_a_up;
- std::unique_ptr<DomainSocket> socket_b_up;
- CreateConnectedSockets<DomainSocket>(file_name.c_str(),
- [=](const DomainSocket &)
- {
- return file_name;
- },
- &socket_a_up, &socket_b_up);
+ std::unique_ptr<Socket> socket_a_up;
+ std::unique_ptr<Socket> socket_b_up;
+ CreateConnectedSockets("unix",
+ file_name.c_str(),
+ [=](const Socket &)
+ {
+ return file_name;
+ },
+ &socket_a_up, &socket_b_up);
}
#endif
TEST_F (SocketTest, TCPListen0ConnectAccept)
{
- std::unique_ptr<TCPSocket> socket_a_up;
- std::unique_ptr<TCPSocket> socket_b_up;
- CreateConnectedSockets<TCPSocket>("127.0.0.1:0",
- [=](const TCPSocket &s)
- {
- char connect_remote_address[64];
- snprintf(connect_remote_address, sizeof(connect_remote_address), "localhost:%u", s.GetLocalPortNumber());
- return std::string(connect_remote_address);
- },
- &socket_a_up, &socket_b_up);
+ std::unique_ptr<Socket> socket_a_up;
+ std::unique_ptr<Socket> socket_b_up;
+ CreateConnectedSockets("tcp",
+ "127.0.0.1:0",
+ [=](const Socket &s)
+ {
+ char connect_remote_address[64];
+ snprintf(connect_remote_address, sizeof(connect_remote_address), "localhost:%u", s.GetLocalPortNumber());
+ return std::string(connect_remote_address);
+ },
+ &socket_a_up, &socket_b_up);
}
TEST_F (SocketTest, TCPGetAddress)
{
- std::unique_ptr<TCPSocket> socket_a_up;
- std::unique_ptr<TCPSocket> socket_b_up;
- CreateConnectedSockets<TCPSocket>("127.0.0.1:0",
- [=](const TCPSocket &s)
- {
- char connect_remote_address[64];
- snprintf(connect_remote_address, sizeof(connect_remote_address), "localhost:%u", s.GetLocalPortNumber());
- return std::string(connect_remote_address);
- },
- &socket_a_up,
- &socket_b_up);
+ std::unique_ptr<Socket> socket_a_up;
+ std::unique_ptr<Socket> socket_b_up;
+ CreateConnectedSockets("tcp",
+ "127.0.0.1:0",
+ [=](const Socket &s)
+ {
+ char connect_remote_address[64];
+ snprintf(connect_remote_address, sizeof(connect_remote_address), "localhost:%u", s.GetLocalPortNumber());
+ return std::string(connect_remote_address);
+ },
+ &socket_a_up,
+ &socket_b_up);
EXPECT_EQ (socket_a_up->GetLocalPortNumber (), socket_b_up->GetRemotePortNumber ());
EXPECT_EQ (socket_b_up->GetLocalPortNumber (), socket_a_up->GetRemotePortNumber ());
Index: tools/lldb-server/lldb-platform.cpp
===================================================================
--- tools/lldb-server/lldb-platform.cpp
+++ tools/lldb-server/lldb-platform.cpp
@@ -32,7 +32,6 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostGetOpt.h"
#include "lldb/Host/OptionParser.h"
-#include "lldb/Host/common/TCPSocket.h"
#include "Acceptor.h"
#include "LLDBServerUtilities.h"
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h"
Index: tools/lldb-server/Acceptor.cpp
===================================================================
--- tools/lldb-server/Acceptor.cpp
+++ tools/lldb-server/Acceptor.cpp
@@ -13,8 +13,9 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/common/TCPSocket.h"
-#include "lldb/Host/posix/DomainSocket.h"
+#include "lldb/Host/Socket.h"
+
+#include "Utility/UriParser.h"
using namespace lldb;
using namespace lldb_private;
@@ -65,20 +66,23 @@
int32_t port = INT32_MIN;
if (Socket::DecodeHostAndPort (name, host_str, port_str, port, &error))
{
- auto tcp_socket = new TCPSocket(child_processes_inherit, error);
- local_socket_id = [tcp_socket]() {
- auto local_port = tcp_socket->GetLocalPortNumber();
- return (local_port != 0) ? std::to_string(local_port) : "";
- };
- listener_socket.reset(tcp_socket);
+ listener_socket = Socket::Create(Socket::TCP, child_processes_inherit, error);
+ if (error.Success())
+ {
+ auto tcp_socket = listener_socket.get();
+ local_socket_id = [tcp_socket]() {
+ auto local_port = tcp_socket->GetLocalPortNumber();
+ return (local_port != 0) ? std::to_string(local_port) : "";
+ };
+ }
}
else
{
const std::string socket_name = name;
local_socket_id = [socket_name](){
return socket_name;
};
- listener_socket.reset(new DomainSocket(child_processes_inherit, error));
+ listener_socket = Socket::Create(Socket::UNIX, child_processes_inherit, error);
}
if (error.Success())
Index: source/Plugins/Socket/UDP/UDPSocket.h
===================================================================
--- /dev/null
+++ source/Plugins/Socket/UDP/UDPSocket.h
@@ -0,0 +1,60 @@
+//===-- UDPSocket.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_UDPSocket_h_
+#define liblldb_UDPSocket_h_
+
+#include "lldb/Host/Socket.h"
+
+namespace lldb_private
+{
+ class UDPSocket: public Socket
+ {
+ public:
+ static Error Connect(llvm::StringRef name, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket);
+
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ static const char *
+ GetPluginDescriptionStatic();
+
+ static Socket*
+ CreateInstance(bool child_processes_inherit, Error &error);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+
+ const char* GetScheme() const override;
+ private:
+ UDPSocket(NativeSocket socket);
+ UDPSocket(bool child_processes_inherit, Error &error);
+
+ size_t Send(const void *buf, const size_t num_bytes) override;
+ Error Connect(llvm::StringRef name) override;
+ Error Listen(llvm::StringRef name, int backlog) override;
+ Error Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket) override;
+
+ SocketAddress m_send_sockaddr;
+ };
+}
+
+#endif // ifndef liblldb_UDPSocket_h_
Index: source/Plugins/Socket/UDP/UDPSocket.cpp
===================================================================
--- /dev/null
+++ source/Plugins/Socket/UDP/UDPSocket.cpp
@@ -0,0 +1,215 @@
+//===-- UdpSocket.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "UDPSocket.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/Config.h"
+
+#ifndef LLDB_DISABLE_POSIX
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#endif
+
+#include <memory>
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+const int kDomain = AF_INET;
+const int kType = SOCK_DGRAM;
+
+const Error kNotSupported("Not supported");
+
+}
+
+UDPSocket::UDPSocket(NativeSocket socket)
+ : Socket(socket, ProtocolUdp, true)
+{
+}
+
+UDPSocket::UDPSocket(bool child_processes_inherit, Error &error)
+ : UDPSocket(CreateSocket(kDomain, kType, 0, child_processes_inherit, error))
+{
+}
+
+void
+UDPSocket::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ CreateInstance);
+}
+
+void
+UDPSocket::Terminate()
+{
+}
+
+ConstString
+UDPSocket::GetPluginNameStatic()
+{
+ static ConstString g_name(UDP);
+ return g_name;
+}
+
+const char *
+UDPSocket::GetPluginDescriptionStatic()
+{
+ return "UDP socket plug-in";
+}
+
+Socket*
+UDPSocket::CreateInstance(bool child_processes_inherit, Error &error)
+{
+ error.Clear();
+ std::unique_ptr<Socket> socket_up(new UDPSocket(child_processes_inherit, error));
+ if (error.Fail())
+ {
+ socket_up.reset();
+ return nullptr;
+ }
+ return socket_up.release();
+}
+
+size_t
+UDPSocket::Send(const void *buf, const size_t num_bytes)
+{
+ return ::sendto (m_socket,
+ static_cast<const char*>(buf),
+ num_bytes,
+ 0,
+ m_send_sockaddr,
+ m_send_sockaddr.GetLength());
+}
+
+Error
+UDPSocket::Connect(llvm::StringRef name)
+{
+ return kNotSupported;
+}
+
+Error
+UDPSocket::Listen(llvm::StringRef name, int backlog)
+{
+ return kNotSupported;
+}
+
+Error
+UDPSocket::Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
+{
+ return kNotSupported;
+}
+
+Error
+UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket)
+{
+ std::unique_ptr<UDPSocket> final_send_socket;
+ std::unique_ptr<UDPSocket> final_recv_socket;
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+ if (log)
+ log->Printf ("UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
+
+ Error error;
+ std::string host_str;
+ std::string port_str;
+ int32_t port = INT32_MIN;
+ if (!DecodeHostAndPort (name, host_str, port_str, port, &error))
+ return error;
+
+ // Setup the receiving end of the UDP connection on this localhost
+ // on port zero. After we bind to port zero we can read the port.
+ final_recv_socket.reset(new UDPSocket(child_processes_inherit, error));
+ if (error.Success())
+ {
+ // Socket was created, now lets bind to the requested port
+ SocketAddress addr;
+ addr.SetToAnyAddress (AF_INET, 0);
+
+ if (::bind (final_recv_socket->GetNativeSocket(), addr, addr.GetLength()) == -1)
+ {
+ // Bind failed...
+ SetLastError (error);
+ }
+ }
+
+ assert(error.Fail() == !(final_recv_socket && final_recv_socket->IsValid()));
+ if (error.Fail())
+ return error;
+
+ // At this point we have setup the receive port, now we need to
+ // setup the UDP send socket
+
+ struct addrinfo hints;
+ struct addrinfo *service_info_list = nullptr;
+
+ ::memset (&hints, 0, sizeof(hints));
+ hints.ai_family = kDomain;
+ hints.ai_socktype = kType;
+ int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list);
+ if (err != 0)
+ {
+ error.SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)",
+ host_str.c_str(),
+ port_str.c_str(),
+ err,
+ gai_strerror(err));
+ return error;
+ }
+
+ for (struct addrinfo *service_info_ptr = service_info_list;
+ service_info_ptr != nullptr;
+ service_info_ptr = service_info_ptr->ai_next)
+ {
+ auto send_fd = CreateSocket (service_info_ptr->ai_family,
+ service_info_ptr->ai_socktype,
+ service_info_ptr->ai_protocol,
+ child_processes_inherit,
+ error);
+ if (error.Success())
+ {
+ final_send_socket.reset(new UDPSocket(send_fd));
+ final_send_socket->m_send_sockaddr = service_info_ptr;
+ break;
+ }
+ else
+ continue;
+ }
+
+ :: freeaddrinfo (service_info_list);
+
+ if (!final_send_socket)
+ return error;
+
+ send_socket = final_send_socket.release();
+ recv_socket = final_recv_socket.release();
+ error.Clear();
+ return error;
+}
+
+ConstString
+UDPSocket::GetPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+UDPSocket::GetPluginVersion()
+{
+ return 1;
+}
+
+const char* UDPSocket::GetScheme() const
+{
+ return GetPluginNameStatic().AsCString();
+}
Index: source/Plugins/Socket/UDP/CMakeLists.txt
===================================================================
--- /dev/null
+++ source/Plugins/Socket/UDP/CMakeLists.txt
@@ -0,0 +1,5 @@
+include_directories(.)
+
+add_lldb_library(lldbPluginUDPSocket
+ UDPSocket.cpp
+ )
Index: source/Plugins/Socket/TCP/TCPSocket.h
===================================================================
--- /dev/null
+++ source/Plugins/Socket/TCP/TCPSocket.h
@@ -0,0 +1,57 @@
+//===-- TCPSocket.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_TCPSocket_h_
+#define liblldb_TCPSocket_h_
+
+#include "lldb/Host/Socket.h"
+
+namespace lldb_private
+{
+ class TCPSocket: public Socket
+ {
+ public:
+ TCPSocket(NativeSocket socket, bool should_close);
+ TCPSocket(bool child_processes_inherit, Error &error);
+
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ static const char *
+ GetPluginDescriptionStatic();
+
+ static Socket*
+ CreateInstance(bool child_processes_inherit, Error &error);
+
+ int SetOptionNoDelay();
+ int SetOptionReuseAddress();
+
+ Error Connect(llvm::StringRef name) override;
+ Error Listen(llvm::StringRef name, int backlog) override;
+ Error Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&conn_socket) override;
+ const char* GetScheme() const override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+ };
+}
+
+#endif // ifndef liblldb_TCPSocket_h_
Index: source/Plugins/Socket/TCP/TCPSocket.cpp
===================================================================
--- /dev/null
+++ source/Plugins/Socket/TCP/TCPSocket.cpp
@@ -0,0 +1,290 @@
+//===-- TcpSocket.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TCPSocket.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/Config.h"
+
+#ifndef LLDB_DISABLE_POSIX
+#include <arpa/inet.h>
+#include <netinet/tcp.h>
+#include <sys/socket.h>
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+const int kDomain = AF_INET;
+const int kType = SOCK_STREAM;
+
+}
+
+TCPSocket::TCPSocket(NativeSocket socket, bool should_close)
+ : Socket(socket, ProtocolTcp, should_close)
+{
+
+}
+
+TCPSocket::TCPSocket(bool child_processes_inherit, Error &error)
+ : TCPSocket(CreateSocket(kDomain, kType, IPPROTO_TCP, child_processes_inherit, error), true)
+{
+}
+
+
+void
+TCPSocket::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ CreateInstance);
+}
+
+void
+TCPSocket::Terminate()
+{
+}
+
+ConstString
+TCPSocket::GetPluginNameStatic()
+{
+ static ConstString g_name(TCP);
+ return g_name;
+}
+
+const char *
+TCPSocket::GetPluginDescriptionStatic()
+{
+ return "TCP socket plug-in";
+}
+
+Socket*
+TCPSocket::CreateInstance(bool child_processes_inherit, Error &error)
+{
+ error.Clear();
+ std::unique_ptr<Socket> socket_up(new TCPSocket(child_processes_inherit, error));
+ if (error.Fail())
+ {
+ socket_up.reset();
+ return nullptr;
+ }
+ return socket_up.release();
+}
+
+Error
+TCPSocket::Connect(llvm::StringRef name)
+{
+ if (m_socket == kInvalidSocketValue)
+ return Error("Invalid socket");
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
+ if (log)
+ log->Printf ("TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
+
+ Error error;
+ std::string host_str;
+ std::string port_str;
+ int32_t port = INT32_MIN;
+ if (!DecodeHostAndPort (name, host_str, port_str, port, &error))
+ return error;
+
+ // Enable local address reuse
+ SetOptionReuseAddress();
+
+ struct sockaddr_in sa;
+ ::memset (&sa, 0, sizeof (sa));
+ sa.sin_family = kDomain;
+ sa.sin_port = htons (port);
+
+ int inet_pton_result = ::inet_pton (kDomain, host_str.c_str(), &sa.sin_addr);
+
+ if (inet_pton_result <= 0)
+ {
+ struct hostent *host_entry = gethostbyname (host_str.c_str());
+ if (host_entry)
+ host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
+ inet_pton_result = ::inet_pton (kDomain, host_str.c_str(), &sa.sin_addr);
+ if (inet_pton_result <= 0)
+ {
+ if (inet_pton_result == -1)
+ SetLastError(error);
+ else
+ error.SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
+
+ return error;
+ }
+ }
+
+ if (-1 == ::connect (GetNativeSocket(), (const struct sockaddr *)&sa, sizeof(sa)))
+ {
+ SetLastError (error);
+ return error;
+ }
+
+ // Keep our TCP packets coming without any delays.
+ SetOptionNoDelay();
+ error.Clear();
+ return error;
+}
+
+Error
+TCPSocket::Listen(llvm::StringRef name, int backlog)
+{
+ Error error;
+
+ // enable local address reuse
+ SetOptionReuseAddress();
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+ if (log)
+ log->Printf ("TCPSocket::%s (%s)", __FUNCTION__, name.data());
+
+ std::string host_str;
+ std::string port_str;
+ int32_t port = INT32_MIN;
+ if (!DecodeHostAndPort (name, host_str, port_str, port, &error))
+ return error;
+
+ SocketAddress bind_addr;
+
+ // Only bind to the loopback address if we are expecting a connection from
+ // localhost to avoid any firewall issues.
+ const bool bind_addr_success = (host_str == "127.0.0.1") ?
+ bind_addr.SetToLocalhost (kDomain, port) :
+ bind_addr.SetToAnyAddress (kDomain, port);
+
+ if (!bind_addr_success)
+ {
+ error.SetErrorString("Failed to bind port");
+ return error;
+ }
+
+ int err = ::bind (GetNativeSocket(), bind_addr, bind_addr.GetLength());
+ if (err != -1)
+ err = ::listen (GetNativeSocket(), backlog);
+
+ if (err == -1)
+ SetLastError (error);
+
+ return error;
+}
+
+Error
+TCPSocket::Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&conn_socket)
+{
+ Error error;
+ std::string host_str;
+ std::string port_str;
+ int32_t port;
+ if (!DecodeHostAndPort(name, host_str, port_str, port, &error))
+ return error;
+
+ const sa_family_t family = kDomain;
+ const int socktype = kType;
+ const int protocol = IPPROTO_TCP;
+ SocketAddress listen_addr;
+ if (host_str.empty())
+ listen_addr.SetToLocalhost(family, port);
+ else if (host_str.compare("*") == 0)
+ listen_addr.SetToAnyAddress(family, port);
+ else
+ {
+ if (!listen_addr.getaddrinfo(host_str.c_str(), port_str.c_str(), family, socktype, protocol))
+ {
+ error.SetErrorStringWithFormat("unable to resolve hostname '%s'", host_str.c_str());
+ return error;
+ }
+ }
+
+ bool accept_connection = false;
+ std::unique_ptr<TCPSocket> accepted_socket;
+
+ // Loop until we are happy with our connection
+ while (!accept_connection)
+ {
+ struct sockaddr_in accept_addr;
+ ::memset (&accept_addr, 0, sizeof accept_addr);
+#if !(defined (__linux__) || defined(_WIN32))
+ accept_addr.sin_len = sizeof accept_addr;
+#endif
+ socklen_t accept_addr_len = sizeof accept_addr;
+
+ int sock = AcceptSocket (GetNativeSocket(),
+ (struct sockaddr *)&accept_addr,
+ &accept_addr_len,
+ child_processes_inherit,
+ error);
+
+ if (error.Fail())
+ break;
+
+ bool is_same_addr = true;
+#if !(defined(__linux__) || (defined(_WIN32)))
+ is_same_addr = (accept_addr_len == listen_addr.sockaddr_in().sin_len);
+#endif
+ if (is_same_addr)
+ is_same_addr = (accept_addr.sin_addr.s_addr == listen_addr.sockaddr_in().sin_addr.s_addr);
+
+ if (is_same_addr || (listen_addr.sockaddr_in().sin_addr.s_addr == INADDR_ANY))
+ {
+ accept_connection = true;
+ accepted_socket.reset(new TCPSocket(sock, true));
+ }
+ else
+ {
+ const uint8_t *accept_ip = (const uint8_t *)&accept_addr.sin_addr.s_addr;
+ const uint8_t *listen_ip = (const uint8_t *)&listen_addr.sockaddr_in().sin_addr.s_addr;
+ ::fprintf (stderr, "error: rejecting incoming connection from %u.%u.%u.%u (expecting %u.%u.%u.%u)\n",
+ accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
+ listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
+ accepted_socket.reset();
+ }
+ }
+
+ if (!accepted_socket)
+ return error;
+
+ // Keep our TCP packets coming without any delays.
+ accepted_socket->SetOptionNoDelay();
+ error.Clear();
+ conn_socket = accepted_socket.release();
+ return error;
+}
+
+int
+TCPSocket::SetOptionNoDelay()
+{
+ return SetOption (IPPROTO_TCP, TCP_NODELAY, 1);
+}
+
+int
+TCPSocket::SetOptionReuseAddress()
+{
+ return SetOption(SOL_SOCKET, SO_REUSEADDR, 1);
+}
+
+ConstString
+TCPSocket::GetPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+TCPSocket::GetPluginVersion()
+{
+ return 1;
+}
+
+const char* TCPSocket::GetScheme() const
+{
+ return GetPluginNameStatic().AsCString();
+}
Index: source/Plugins/Socket/TCP/CMakeLists.txt
===================================================================
--- /dev/null
+++ source/Plugins/Socket/TCP/CMakeLists.txt
@@ -0,0 +1,5 @@
+include_directories(.)
+
+add_lldb_library(lldbPluginTCPSocket
+ TCPSocket.cpp
+ )
Index: source/Plugins/Socket/POSIX/DomainSocket.h
===================================================================
--- /dev/null
+++ source/Plugins/Socket/POSIX/DomainSocket.h
@@ -0,0 +1,62 @@
+//===-- DomainSocket.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_DomainSocket_h_
+#define liblldb_DomainSocket_h_
+
+#include "lldb/Host/Socket.h"
+
+namespace lldb_private
+{
+ class DomainSocket: public Socket
+ {
+ public:
+ DomainSocket(bool child_processes_inherit, Error &error);
+
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ static const char *
+ GetPluginDescriptionStatic();
+
+ static Socket*
+ CreateInstance(bool child_processes_inherit, Error &error);
+
+ Error Connect(llvm::StringRef name) override;
+ Error Listen(llvm::StringRef name, int backlog) override;
+ Error Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket) override;
+ const char* GetScheme() const override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+
+ protected:
+ DomainSocket(SocketProtocol protocol, bool child_processes_inherit, Error &error);
+
+ virtual size_t GetNameOffset() const;
+ virtual void DeleteSocketFile(llvm::StringRef name);
+
+ private:
+ DomainSocket(NativeSocket socket);
+ };
+}
+
+#endif // ifndef liblldb_DomainSocket_h_
Index: source/Plugins/Socket/POSIX/DomainSocket.cpp
===================================================================
--- /dev/null
+++ source/Plugins/Socket/POSIX/DomainSocket.cpp
@@ -0,0 +1,174 @@
+//===-- DomainSocket.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DomainSocket.h"
+
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/FileSystem.h"
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+#ifdef __ANDROID__
+// Android does not have SUN_LEN
+#ifndef SUN_LEN
+#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path))
+#endif
+#endif // #ifdef __ANDROID__
+
+namespace {
+
+const int kDomain = AF_UNIX;
+const int kType = SOCK_STREAM;
+
+bool SetSockAddr(llvm::StringRef name, const size_t name_offset, sockaddr_un* saddr_un)
+{
+ if (name.size() + name_offset > sizeof(saddr_un->sun_path))
+ return false;
+
+ saddr_un->sun_family = kDomain;
+ memset(saddr_un->sun_path, 0, sizeof(saddr_un->sun_path));
+
+ strncpy(&saddr_un->sun_path[name_offset], name.data(), name.size());
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
+ saddr_un->sun_len = SUN_LEN (saddr_un);
+#endif
+ return true;
+}
+
+}
+
+DomainSocket::DomainSocket(NativeSocket socket)
+ : Socket(socket, ProtocolUnixDomain, true)
+{
+}
+
+DomainSocket::DomainSocket(bool child_processes_inherit, Error &error)
+ : DomainSocket(CreateSocket(kDomain, kType, 0, child_processes_inherit, error))
+{
+}
+
+DomainSocket::DomainSocket(SocketProtocol protocol, bool child_processes_inherit, Error &error)
+ : Socket(CreateSocket(kDomain, kType, 0, child_processes_inherit, error), protocol, true)
+{
+}
+
+void
+DomainSocket::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ CreateInstance);
+}
+
+void
+DomainSocket::Terminate()
+{
+}
+
+ConstString
+DomainSocket::GetPluginNameStatic()
+{
+ static ConstString g_name(UNIX);
+ return g_name;
+}
+
+const char *
+DomainSocket::GetPluginDescriptionStatic()
+{
+ return "Unix domain socket plug-in";
+}
+
+Socket*
+DomainSocket::CreateInstance(bool child_processes_inherit, Error &error)
+{
+ error.Clear();
+ std::unique_ptr<Socket> socket_up(new DomainSocket(child_processes_inherit, error));
+ if (error.Fail())
+ {
+ socket_up.reset();
+ return nullptr;
+ }
+ return socket_up.release();
+}
+
+Error
+DomainSocket::Connect(llvm::StringRef name)
+{
+ sockaddr_un saddr_un;
+ if (!SetSockAddr(name, GetNameOffset(), &saddr_un))
+ return Error("Failed to set socket address");
+
+ Error error;
+ if (::connect(GetNativeSocket(), (struct sockaddr *)&saddr_un, sizeof(saddr_un)) < 0)
+ SetLastError (error);
+
+ return error;
+}
+
+Error
+DomainSocket::Listen(llvm::StringRef name, int backlog)
+{
+ sockaddr_un saddr_un;
+ if (!SetSockAddr(name, GetNameOffset(), &saddr_un))
+ return Error("Failed to set socket address");
+
+ DeleteSocketFile(name);
+
+ Error error;
+ if (::bind(GetNativeSocket(), (struct sockaddr *)&saddr_un, sizeof(saddr_un)) == 0)
+ if (::listen(GetNativeSocket(), backlog) == 0)
+ return error;
+
+ SetLastError(error);
+ return error;
+}
+
+Error
+DomainSocket::Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
+{
+ Error error;
+ auto conn_fd = AcceptSocket(GetNativeSocket(), nullptr, nullptr, child_processes_inherit, error);
+ if (error.Success())
+ socket = new DomainSocket(conn_fd);
+
+ return error;
+}
+
+size_t
+DomainSocket::GetNameOffset() const
+{
+ return 0;
+}
+
+void
+DomainSocket::DeleteSocketFile(llvm::StringRef name)
+{
+ FileSystem::Unlink(FileSpec{name, true});
+}
+
+ConstString
+DomainSocket::GetPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+DomainSocket::GetPluginVersion()
+{
+ return 1;
+}
+
+const char* DomainSocket::GetScheme() const
+{
+ return GetPluginNameStatic().AsCString();
+}
Index: source/Plugins/Socket/POSIX/CMakeLists.txt
===================================================================
--- /dev/null
+++ source/Plugins/Socket/POSIX/CMakeLists.txt
@@ -0,0 +1,5 @@
+include_directories(.)
+
+add_lldb_library(lldbPluginPOSIXSocket
+ DomainSocket.cpp
+ )
Index: source/Plugins/Socket/Linux/CMakeLists.txt
===================================================================
--- /dev/null
+++ source/Plugins/Socket/Linux/CMakeLists.txt
@@ -0,0 +1,5 @@
+include_directories(.)
+
+add_lldb_library(lldbPluginLinuxSocket
+ AbstractSocket.cpp
+ )
Index: source/Plugins/Socket/Linux/AbstractSocket.h
===================================================================
--- /dev/null
+++ source/Plugins/Socket/Linux/AbstractSocket.h
@@ -0,0 +1,54 @@
+//===-- AbstractSocket.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_AbstractSocket_h_
+#define liblldb_AbstractSocket_h_
+
+#include "Plugins/Socket/POSIX/DomainSocket.h"
+
+namespace lldb_private
+{
+ class AbstractSocket: public DomainSocket
+ {
+ public:
+ AbstractSocket(bool child_processes_inherit, Error &error);
+
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ static const char *
+ GetPluginDescriptionStatic();
+
+ static Socket*
+ CreateInstance(bool child_processes_inherit, Error &error);
+
+ const char* GetScheme() const override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+
+ protected:
+ size_t GetNameOffset() const override;
+ void DeleteSocketFile(llvm::StringRef name) override;
+ };
+}
+
+#endif // ifndef liblldb_AbstractSocket_h_
Index: source/Plugins/Socket/Linux/AbstractSocket.cpp
===================================================================
--- /dev/null
+++ source/Plugins/Socket/Linux/AbstractSocket.cpp
@@ -0,0 +1,90 @@
+//===-- AbstractSocket.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AbstractSocket.h"
+
+#include "llvm/ADT/StringRef.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/PluginManager.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+AbstractSocket::AbstractSocket(bool child_processes_inherit, Error &error)
+ : DomainSocket(ProtocolUnixAbstract, child_processes_inherit, error)
+{
+}
+
+void
+AbstractSocket::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ CreateInstance);
+}
+
+void
+AbstractSocket::Terminate()
+{
+}
+
+ConstString
+AbstractSocket::GetPluginNameStatic()
+{
+ static ConstString g_name(UNIX_ABSTRACT);
+ return g_name;
+}
+
+const char *
+AbstractSocket::GetPluginDescriptionStatic()
+{
+ return "Unix domain abstract socket plug-in";
+}
+
+Socket*
+AbstractSocket::CreateInstance(bool child_processes_inherit, Error &error)
+{
+ error.Clear();
+ std::unique_ptr<Socket> socket_up(new AbstractSocket(child_processes_inherit, error));
+ if (error.Fail())
+ {
+ socket_up.reset();
+ return nullptr;
+ }
+ return socket_up.release();
+}
+
+size_t
+AbstractSocket::GetNameOffset() const
+{
+ return 1;
+}
+
+void
+AbstractSocket::DeleteSocketFile(llvm::StringRef name)
+{
+}
+
+ConstString
+AbstractSocket::GetPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+AbstractSocket::GetPluginVersion()
+{
+ return 1;
+}
+
+const char* AbstractSocket::GetScheme() const
+{
+ return GetPluginNameStatic().AsCString();
+}
Index: source/Plugins/Socket/CMakeLists.txt
===================================================================
--- /dev/null
+++ source/Plugins/Socket/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_subdirectory(TCP)
+add_subdirectory(UDP)
+if (CMAKE_HOST_UNIX)
+ add_subdirectory(POSIX)
+endif()
+if (CMAKE_SYSTEM_NAME MATCHES "Linux")
+ add_subdirectory(Linux)
+endif()
Index: source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
===================================================================
--- source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -25,7 +25,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/common/TCPSocket.h"
+#include "lldb/Host/Socket.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
@@ -276,7 +276,7 @@
if (conn_ap->IsConnected())
{
- const TCPSocket& socket = static_cast<const TCPSocket&>(*conn_ap->GetReadObject());
+ const Socket& socket = static_cast<const Socket&>(*conn_ap->GetReadObject());
const uint16_t reply_port = socket.GetLocalPortNumber();
if (reply_port != 0)
Index: source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
===================================================================
--- source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -10,7 +10,7 @@
// Other libraries and framework includes
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
-#include "lldb/Host/common/TCPSocket.h"
+#include "lldb/Host/Socket.h"
#include "AdbClient.h"
#include "PlatformAndroidRemoteGDBServer.h"
#include "Utility/UriParser.h"
@@ -63,7 +63,7 @@
FindUnusedPort (uint16_t& port)
{
Error error;
- std::unique_ptr<TCPSocket> tcp_socket(new TCPSocket(false, error));
+ const std::unique_ptr<Socket> tcp_socket(Socket::Create("tcp", false, error));
if (error.Fail())
return error;
Index: source/Plugins/CMakeLists.txt
===================================================================
--- source/Plugins/CMakeLists.txt
+++ source/Plugins/CMakeLists.txt
@@ -14,6 +14,7 @@
add_subdirectory(Platform)
add_subdirectory(Process)
add_subdirectory(ScriptInterpreter)
+add_subdirectory(Socket)
add_subdirectory(SymbolFile)
add_subdirectory(SystemRuntime)
add_subdirectory(SymbolVendor)
Index: source/Initialization/SystemInitializerCommon.cpp
===================================================================
--- source/Initialization/SystemInitializerCommon.cpp
+++ source/Initialization/SystemInitializerCommon.cpp
@@ -11,6 +11,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/Socket.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/GoASTContext.h"
@@ -96,6 +97,7 @@
Log::Initialize();
HostInfo::Initialize();
+ Socket::Initialize();
Timer::Initialize();
Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
Index: source/Host/posix/DomainSocket.cpp
===================================================================
--- source/Host/posix/DomainSocket.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-//===-- DomainSocket.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/posix/DomainSocket.h"
-
-#include "lldb/Host/FileSystem.h"
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-using namespace lldb;
-using namespace lldb_private;
-
-#ifdef __ANDROID__
-// Android does not have SUN_LEN
-#ifndef SUN_LEN
-#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path))
-#endif
-#endif // #ifdef __ANDROID__
-
-namespace {
-
-const int kDomain = AF_UNIX;
-const int kType = SOCK_STREAM;
-
-bool SetSockAddr(llvm::StringRef name, const size_t name_offset, sockaddr_un* saddr_un)
-{
- if (name.size() + name_offset > sizeof(saddr_un->sun_path))
- return false;
-
- saddr_un->sun_family = kDomain;
- memset(saddr_un->sun_path, 0, sizeof(saddr_un->sun_path));
-
- strncpy(&saddr_un->sun_path[name_offset], name.data(), name.size());
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
- saddr_un->sun_len = SUN_LEN (saddr_un);
-#endif
- return true;
-}
-
-}
-
-DomainSocket::DomainSocket(NativeSocket socket)
- : Socket(socket, ProtocolUnixDomain, true)
-{
-}
-
-DomainSocket::DomainSocket(bool child_processes_inherit, Error &error)
- : DomainSocket(CreateSocket(kDomain, kType, 0, child_processes_inherit, error))
-{
-}
-
-DomainSocket::DomainSocket(SocketProtocol protocol, bool child_processes_inherit, Error &error)
- : Socket(CreateSocket(kDomain, kType, 0, child_processes_inherit, error), protocol, true)
-{
-}
-
-Error
-DomainSocket::Connect(llvm::StringRef name)
-{
- sockaddr_un saddr_un;
- if (!SetSockAddr(name, GetNameOffset(), &saddr_un))
- return Error("Failed to set socket address");
-
- Error error;
- if (::connect(GetNativeSocket(), (struct sockaddr *)&saddr_un, sizeof(saddr_un)) < 0)
- SetLastError (error);
-
- return error;
-}
-
-Error
-DomainSocket::Listen(llvm::StringRef name, int backlog)
-{
- sockaddr_un saddr_un;
- if (!SetSockAddr(name, GetNameOffset(), &saddr_un))
- return Error("Failed to set socket address");
-
- DeleteSocketFile(name);
-
- Error error;
- if (::bind(GetNativeSocket(), (struct sockaddr *)&saddr_un, sizeof(saddr_un)) == 0)
- if (::listen(GetNativeSocket(), backlog) == 0)
- return error;
-
- SetLastError(error);
- return error;
-}
-
-Error
-DomainSocket::Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
-{
- Error error;
- auto conn_fd = AcceptSocket(GetNativeSocket(), nullptr, nullptr, child_processes_inherit, error);
- if (error.Success())
- socket = new DomainSocket(conn_fd);
-
- return error;
-}
-
-size_t
-DomainSocket::GetNameOffset() const
-{
- return 0;
-}
-
-void
-DomainSocket::DeleteSocketFile(llvm::StringRef name)
-{
- FileSystem::Unlink(FileSpec{name, true});
-}
Index: source/Host/posix/ConnectionFileDescriptorPosix.cpp
===================================================================
--- source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -47,8 +47,8 @@
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Socket.h"
-#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Interpreter/Args.h"
+#include "Plugins/Socket/TCP/TCPSocket.h"
using namespace lldb;
using namespace lldb_private;
Index: source/Host/linux/AbstractSocket.cpp
===================================================================
--- source/Host/linux/AbstractSocket.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-//===-- AbstractSocket.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/linux/AbstractSocket.h"
-
-#include "llvm/ADT/StringRef.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-AbstractSocket::AbstractSocket(bool child_processes_inherit, Error &error)
- : DomainSocket(ProtocolUnixAbstract, child_processes_inherit, error)
-{
-}
-
-size_t
-AbstractSocket::GetNameOffset() const
-{
- return 1;
-}
-
-void
-AbstractSocket::DeleteSocketFile(llvm::StringRef name)
-{
-}
Index: source/Host/common/UDPSocket.cpp
===================================================================
--- source/Host/common/UDPSocket.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-//===-- UdpSocket.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/common/UDPSocket.h"
-
-#include "lldb/Core/Log.h"
-#include "lldb/Host/Config.h"
-
-#ifndef LLDB_DISABLE_POSIX
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#endif
-
-#include <memory>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-const int kDomain = AF_INET;
-const int kType = SOCK_DGRAM;
-
-const Error kNotSupported("Not supported");
-
-}
-
-UDPSocket::UDPSocket(NativeSocket socket)
- : Socket(socket, ProtocolUdp, true)
-{
-}
-
-UDPSocket::UDPSocket(bool child_processes_inherit, Error &error)
- : UDPSocket(CreateSocket(kDomain, kType, 0, child_processes_inherit, error))
-{
-}
-
-size_t
-UDPSocket::Send(const void *buf, const size_t num_bytes)
-{
- return ::sendto (m_socket,
- static_cast<const char*>(buf),
- num_bytes,
- 0,
- m_send_sockaddr,
- m_send_sockaddr.GetLength());
-}
-
-Error
-UDPSocket::Connect(llvm::StringRef name)
-{
- return kNotSupported;
-}
-
-Error
-UDPSocket::Listen(llvm::StringRef name, int backlog)
-{
- return kNotSupported;
-}
-
-Error
-UDPSocket::Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
-{
- return kNotSupported;
-}
-
-Error
-UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket)
-{
- std::unique_ptr<UDPSocket> final_send_socket;
- std::unique_ptr<UDPSocket> final_recv_socket;
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf ("UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
-
- Error error;
- std::string host_str;
- std::string port_str;
- int32_t port = INT32_MIN;
- if (!DecodeHostAndPort (name, host_str, port_str, port, &error))
- return error;
-
- // Setup the receiving end of the UDP connection on this localhost
- // on port zero. After we bind to port zero we can read the port.
- final_recv_socket.reset(new UDPSocket(child_processes_inherit, error));
- if (error.Success())
- {
- // Socket was created, now lets bind to the requested port
- SocketAddress addr;
- addr.SetToAnyAddress (AF_INET, 0);
-
- if (::bind (final_recv_socket->GetNativeSocket(), addr, addr.GetLength()) == -1)
- {
- // Bind failed...
- SetLastError (error);
- }
- }
-
- assert(error.Fail() == !(final_recv_socket && final_recv_socket->IsValid()));
- if (error.Fail())
- return error;
-
- // At this point we have setup the receive port, now we need to
- // setup the UDP send socket
-
- struct addrinfo hints;
- struct addrinfo *service_info_list = nullptr;
-
- ::memset (&hints, 0, sizeof(hints));
- hints.ai_family = kDomain;
- hints.ai_socktype = kType;
- int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list);
- if (err != 0)
- {
- error.SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)",
- host_str.c_str(),
- port_str.c_str(),
- err,
- gai_strerror(err));
- return error;
- }
-
- for (struct addrinfo *service_info_ptr = service_info_list;
- service_info_ptr != nullptr;
- service_info_ptr = service_info_ptr->ai_next)
- {
- auto send_fd = CreateSocket (service_info_ptr->ai_family,
- service_info_ptr->ai_socktype,
- service_info_ptr->ai_protocol,
- child_processes_inherit,
- error);
- if (error.Success())
- {
- final_send_socket.reset(new UDPSocket(send_fd));
- final_send_socket->m_send_sockaddr = service_info_ptr;
- break;
- }
- else
- continue;
- }
-
- :: freeaddrinfo (service_info_list);
-
- if (!final_send_socket)
- return error;
-
- send_socket = final_send_socket.release();
- recv_socket = final_recv_socket.release();
- error.Clear();
- return error;
-}
Index: source/Host/common/TCPSocket.cpp
===================================================================
--- source/Host/common/TCPSocket.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-//===-- TcpSocket.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/common/TCPSocket.h"
-
-#include "lldb/Core/Log.h"
-#include "lldb/Host/Config.h"
-
-#ifndef LLDB_DISABLE_POSIX
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
-#include <sys/socket.h>
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-const int kDomain = AF_INET;
-const int kType = SOCK_STREAM;
-
-}
-
-TCPSocket::TCPSocket(NativeSocket socket, bool should_close)
- : Socket(socket, ProtocolTcp, should_close)
-{
-
-}
-
-TCPSocket::TCPSocket(bool child_processes_inherit, Error &error)
- : TCPSocket(CreateSocket(kDomain, kType, IPPROTO_TCP, child_processes_inherit, error), true)
-{
-}
-
-
-// Return the port number that is being used by the socket.
-uint16_t
-TCPSocket::GetLocalPortNumber() const
-{
- if (m_socket != kInvalidSocketValue)
- {
- SocketAddress sock_addr;
- socklen_t sock_addr_len = sock_addr.GetMaxLength ();
- if (::getsockname (m_socket, sock_addr, &sock_addr_len) == 0)
- return sock_addr.GetPort ();
- }
- return 0;
-}
-
-std::string
-TCPSocket::GetLocalIPAddress() const
-{
- // We bound to port zero, so we need to figure out which port we actually bound to
- if (m_socket != kInvalidSocketValue)
- {
- SocketAddress sock_addr;
- socklen_t sock_addr_len = sock_addr.GetMaxLength ();
- if (::getsockname (m_socket, sock_addr, &sock_addr_len) == 0)
- return sock_addr.GetIPAddress ();
- }
- return "";
-}
-
-uint16_t
-TCPSocket::GetRemotePortNumber() const
-{
- if (m_socket != kInvalidSocketValue)
- {
- SocketAddress sock_addr;
- socklen_t sock_addr_len = sock_addr.GetMaxLength ();
- if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
- return sock_addr.GetPort ();
- }
- return 0;
-}
-
-std::string
-TCPSocket::GetRemoteIPAddress () const
-{
- // We bound to port zero, so we need to figure out which port we actually bound to
- if (m_socket != kInvalidSocketValue)
- {
- SocketAddress sock_addr;
- socklen_t sock_addr_len = sock_addr.GetMaxLength ();
- if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
- return sock_addr.GetIPAddress ();
- }
- return "";
-}
-
-Error
-TCPSocket::Connect(llvm::StringRef name)
-{
- if (m_socket == kInvalidSocketValue)
- return Error("Invalid socket");
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
- if (log)
- log->Printf ("TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
-
- Error error;
- std::string host_str;
- std::string port_str;
- int32_t port = INT32_MIN;
- if (!DecodeHostAndPort (name, host_str, port_str, port, &error))
- return error;
-
- // Enable local address reuse
- SetOptionReuseAddress();
-
- struct sockaddr_in sa;
- ::memset (&sa, 0, sizeof (sa));
- sa.sin_family = kDomain;
- sa.sin_port = htons (port);
-
- int inet_pton_result = ::inet_pton (kDomain, host_str.c_str(), &sa.sin_addr);
-
- if (inet_pton_result <= 0)
- {
- struct hostent *host_entry = gethostbyname (host_str.c_str());
- if (host_entry)
- host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
- inet_pton_result = ::inet_pton (kDomain, host_str.c_str(), &sa.sin_addr);
- if (inet_pton_result <= 0)
- {
- if (inet_pton_result == -1)
- SetLastError(error);
- else
- error.SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
-
- return error;
- }
- }
-
- if (-1 == ::connect (GetNativeSocket(), (const struct sockaddr *)&sa, sizeof(sa)))
- {
- SetLastError (error);
- return error;
- }
-
- // Keep our TCP packets coming without any delays.
- SetOptionNoDelay();
- error.Clear();
- return error;
-}
-
-Error
-TCPSocket::Listen(llvm::StringRef name, int backlog)
-{
- Error error;
-
- // enable local address reuse
- SetOptionReuseAddress();
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf ("TCPSocket::%s (%s)", __FUNCTION__, name.data());
-
- std::string host_str;
- std::string port_str;
- int32_t port = INT32_MIN;
- if (!DecodeHostAndPort (name, host_str, port_str, port, &error))
- return error;
-
- SocketAddress bind_addr;
-
- // Only bind to the loopback address if we are expecting a connection from
- // localhost to avoid any firewall issues.
- const bool bind_addr_success = (host_str == "127.0.0.1") ?
- bind_addr.SetToLocalhost (kDomain, port) :
- bind_addr.SetToAnyAddress (kDomain, port);
-
- if (!bind_addr_success)
- {
- error.SetErrorString("Failed to bind port");
- return error;
- }
-
- int err = ::bind (GetNativeSocket(), bind_addr, bind_addr.GetLength());
- if (err != -1)
- err = ::listen (GetNativeSocket(), backlog);
-
- if (err == -1)
- SetLastError (error);
-
- return error;
-}
-
-Error
-TCPSocket::Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&conn_socket)
-{
- Error error;
- std::string host_str;
- std::string port_str;
- int32_t port;
- if (!DecodeHostAndPort(name, host_str, port_str, port, &error))
- return error;
-
- const sa_family_t family = kDomain;
- const int socktype = kType;
- const int protocol = IPPROTO_TCP;
- SocketAddress listen_addr;
- if (host_str.empty())
- listen_addr.SetToLocalhost(family, port);
- else if (host_str.compare("*") == 0)
- listen_addr.SetToAnyAddress(family, port);
- else
- {
- if (!listen_addr.getaddrinfo(host_str.c_str(), port_str.c_str(), family, socktype, protocol))
- {
- error.SetErrorStringWithFormat("unable to resolve hostname '%s'", host_str.c_str());
- return error;
- }
- }
-
- bool accept_connection = false;
- std::unique_ptr<TCPSocket> accepted_socket;
-
- // Loop until we are happy with our connection
- while (!accept_connection)
- {
- struct sockaddr_in accept_addr;
- ::memset (&accept_addr, 0, sizeof accept_addr);
-#if !(defined (__linux__) || defined(_WIN32))
- accept_addr.sin_len = sizeof accept_addr;
-#endif
- socklen_t accept_addr_len = sizeof accept_addr;
-
- int sock = AcceptSocket (GetNativeSocket(),
- (struct sockaddr *)&accept_addr,
- &accept_addr_len,
- child_processes_inherit,
- error);
-
- if (error.Fail())
- break;
-
- bool is_same_addr = true;
-#if !(defined(__linux__) || (defined(_WIN32)))
- is_same_addr = (accept_addr_len == listen_addr.sockaddr_in().sin_len);
-#endif
- if (is_same_addr)
- is_same_addr = (accept_addr.sin_addr.s_addr == listen_addr.sockaddr_in().sin_addr.s_addr);
-
- if (is_same_addr || (listen_addr.sockaddr_in().sin_addr.s_addr == INADDR_ANY))
- {
- accept_connection = true;
- accepted_socket.reset(new TCPSocket(sock, true));
- }
- else
- {
- const uint8_t *accept_ip = (const uint8_t *)&accept_addr.sin_addr.s_addr;
- const uint8_t *listen_ip = (const uint8_t *)&listen_addr.sockaddr_in().sin_addr.s_addr;
- ::fprintf (stderr, "error: rejecting incoming connection from %u.%u.%u.%u (expecting %u.%u.%u.%u)\n",
- accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
- listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
- accepted_socket.reset();
- }
- }
-
- if (!accepted_socket)
- return error;
-
- // Keep our TCP packets coming without any delays.
- accepted_socket->SetOptionNoDelay();
- error.Clear();
- conn_socket = accepted_socket.release();
- return error;
-}
-
-int
-TCPSocket::SetOptionNoDelay()
-{
- return SetOption (IPPROTO_TCP, TCP_NODELAY, 1);
-}
-
-int
-TCPSocket::SetOptionReuseAddress()
-{
- return SetOption(SOL_SOCKET, SO_REUSEADDR, 1);
-}
Index: source/Host/common/Socket.cpp
===================================================================
--- source/Host/common/Socket.cpp
+++ source/Host/common/Socket.cpp
@@ -10,17 +10,19 @@
#include "lldb/Host/Socket.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/SocketAddress.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/TimeValue.h"
-#include "lldb/Host/common/TCPSocket.h"
-#include "lldb/Host/common/UDPSocket.h"
+
+#include "Plugins/Socket/TCP/TCPSocket.h"
+#include "Plugins/Socket/UDP/UDPSocket.h"
#ifndef LLDB_DISABLE_POSIX
-#include "lldb/Host/posix/DomainSocket.h"
+#include "Plugins/Socket/POSIX/DomainSocket.h"
#include <arpa/inet.h>
#include <netdb.h>
@@ -31,9 +33,11 @@
#endif
#ifdef __linux__
-#include "lldb/Host/linux/AbstractSocket.h"
+#include "Plugins/Socket/Linux/AbstractSocket.h"
#endif
+#include <mutex>
+
#ifdef __ANDROID_NDK__
#include <linux/tcp.h>
#include <bits/error_constants.h>
@@ -73,6 +77,11 @@
}
+const char * Socket::TCP = "tcp";
+const char * Socket::UDP = "udp";
+const char * Socket::UNIX = "unix";
+const char * Socket::UNIX_ABSTRACT = "unix-abstract";
+
Socket::Socket(NativeSocket socket, SocketProtocol protocol, bool should_close)
: IOObject(eFDTypeSocket, should_close)
, m_protocol(protocol)
@@ -86,20 +95,47 @@
Close();
}
+std::unique_ptr<Socket> Socket::Create(const char* scheme, bool child_processes_inherit, Error& error)
+{
+ ConstString const_plugin_name(scheme);
+ auto create_callback = PluginManager::GetSocketCreateCallbackForPluginName (const_plugin_name);
+ if (!create_callback)
+ return std::unique_ptr<Socket>();
+
+ return std::unique_ptr<Socket>(create_callback(child_processes_inherit, error));
+}
+
+void Socket::Initialize()
+{
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, [](){
+ TCPSocket::Initialize();
+ UDPSocket::Initialize();
+
+#ifndef LLDB_DISABLE_POSIX
+ DomainSocket::Initialize();
+#endif
+
+#ifdef __linux__
+ AbstractSocket::Initialize();
+#endif
+ });
+}
+
Error Socket::TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket)
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
if (log)
log->Printf ("Socket::%s (host/port = %s)", __FUNCTION__, host_and_port.data());
Error error;
- std::unique_ptr<TCPSocket> connect_socket(new TCPSocket(child_processes_inherit, error));
+ auto socket_up(Create(TCP, child_processes_inherit, error));
if (error.Fail())
return error;
- error = connect_socket->Connect(host_and_port);
+ error = socket_up->Connect(host_and_port);
if (error.Success())
- socket = connect_socket.release();
+ socket = socket_up.release();
return error;
}
@@ -122,28 +158,28 @@
if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, &error))
return error;
- std::unique_ptr<TCPSocket> listen_socket(new TCPSocket(child_processes_inherit, error));
+ auto socket_up(Create(TCP, child_processes_inherit, error));
if (error.Fail())
return error;
- error = listen_socket->Listen(host_and_port, backlog);
+ error = socket_up->Listen(host_and_port, backlog);
if (error.Success())
{
// We were asked to listen on port zero which means we
// must now read the actual port that was given to us
// as port zero is a special code for "find an open port
// for me".
if (port == 0)
- port = listen_socket->GetLocalPortNumber();
+ port = socket_up->GetLocalPortNumber();
// Set the port predicate since when doing a listen://<host>:<port>
// it often needs to accept the incoming connection which is a blocking
// system call. Allowing access to the bound port using a predicate allows
// us to wait for the port predicate to be set to a non-zero value from
// another thread in an efficient manor.
if (predicate)
predicate->SetValue (port, eBroadcastAlways);
- socket = listen_socket.release();
+ socket = socket_up.release();
}
return error;
@@ -162,13 +198,13 @@
{
Error error;
#ifndef LLDB_DISABLE_POSIX
- std::unique_ptr<DomainSocket> connect_socket(new DomainSocket(child_processes_inherit, error));
+ auto socket_up(Create(UNIX, child_processes_inherit, error));
if (error.Fail())
return error;
- error = connect_socket->Connect(name);
+ error = socket_up->Connect(name);
if (error.Success())
- socket = connect_socket.release();
+ socket = socket_up.release();
#else
error.SetErrorString("Unix domain sockets are not supported on this platform.");
#endif
@@ -179,15 +215,15 @@
{
Error error;
#ifndef LLDB_DISABLE_POSIX
- std::unique_ptr<DomainSocket> listen_socket(new DomainSocket(child_processes_inherit, error));
+ auto socket_up(Create(UNIX, child_processes_inherit, error));
if (error.Fail())
return error;
- error = listen_socket->Listen(name, 5);
+ error = socket_up->Listen(name, 5);
if (error.Fail())
return error;
- error = listen_socket->Accept(name, child_processes_inherit, socket);
+ error = socket_up->Accept(name, child_processes_inherit, socket);
#else
error.SetErrorString("Unix domain sockets are not supported on this platform.");
#endif
@@ -199,13 +235,13 @@
{
Error error;
#ifdef __linux__
- std::unique_ptr<Socket> connect_socket(new AbstractSocket(child_processes_inherit, error));
+ auto socket_up(Create(UNIX_ABSTRACT, child_processes_inherit, error));
if (error.Fail())
return error;
- error = connect_socket->Connect(name);
+ error = socket_up->Connect(name);
if (error.Success())
- socket = connect_socket.release();
+ socket = socket_up.release();
#else
error.SetErrorString("Abstract domain sockets are not supported on this platform.");
#endif
@@ -217,15 +253,15 @@
{
Error error;
#ifdef __linux__
- std::unique_ptr<Socket> listen_socket(new AbstractSocket(child_processes_inherit, error));
+ auto socket_up(Create(UNIX_ABSTRACT, child_processes_inherit, error));
if (error.Fail())
return error;
- error = listen_socket->Listen(name, 5);
+ error = socket_up->Listen(name, 5);
if (error.Fail())
return error;
- error = listen_socket->Accept(name, child_processes_inherit, socket);
+ error = socket_up->Accept(name, child_processes_inherit, socket);
#else
error.SetErrorString("Abstract domain sockets are not supported on this platform.");
#endif
@@ -467,3 +503,58 @@
SetLastError(error);
return fd;
}
+
+// Return the port number that is being used by the socket.
+uint16_t
+Socket::GetLocalPortNumber() const
+{
+ if (m_socket != kInvalidSocketValue)
+ {
+ SocketAddress sock_addr;
+ socklen_t sock_addr_len = sock_addr.GetMaxLength ();
+ if (::getsockname (m_socket, sock_addr, &sock_addr_len) == 0)
+ return sock_addr.GetPort ();
+ }
+ return 0;
+}
+
+std::string
+Socket::GetLocalIPAddress() const
+{
+ // We bound to port zero, so we need to figure out which port we actually bound to
+ if (m_socket != kInvalidSocketValue)
+ {
+ SocketAddress sock_addr;
+ socklen_t sock_addr_len = sock_addr.GetMaxLength ();
+ if (::getsockname (m_socket, sock_addr, &sock_addr_len) == 0)
+ return sock_addr.GetIPAddress ();
+ }
+ return "";
+}
+
+uint16_t
+Socket::GetRemotePortNumber() const
+{
+ if (m_socket != kInvalidSocketValue)
+ {
+ SocketAddress sock_addr;
+ socklen_t sock_addr_len = sock_addr.GetMaxLength ();
+ if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
+ return sock_addr.GetPort ();
+ }
+ return 0;
+}
+
+std::string
+Socket::GetRemoteIPAddress () const
+{
+ // We bound to port zero, so we need to figure out which port we actually bound to
+ if (m_socket != kInvalidSocketValue)
+ {
+ SocketAddress sock_addr;
+ socklen_t sock_addr_len = sock_addr.GetMaxLength ();
+ if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
+ return sock_addr.GetIPAddress ();
+ }
+ return "";
+}
Index: source/Host/CMakeLists.txt
===================================================================
--- source/Host/CMakeLists.txt
+++ source/Host/CMakeLists.txt
@@ -34,13 +34,11 @@
common/SoftwareBreakpoint.cpp
common/StringConvert.cpp
common/Symbols.cpp
- common/TCPSocket.cpp
common/Terminal.cpp
common/ThisThread.cpp
common/ThreadLauncher.cpp
common/TimeValue.cpp
common/XML.cpp
- common/UDPSocket.cpp
)
# Keep track of whether we want to provide a define for the
@@ -83,7 +81,6 @@
endif()
add_host_subdirectory(posix
- posix/DomainSocket.cpp
posix/FileSystem.cpp
posix/HostInfoPosix.cpp
posix/HostProcessPosix.cpp
@@ -121,16 +118,14 @@
android/HostInfoAndroid.cpp
android/LibcGlue.cpp
android/ProcessLauncherAndroid.cpp
- linux/AbstractSocket.cpp
linux/Host.cpp
linux/HostInfoLinux.cpp
linux/HostThreadLinux.cpp
linux/LibcGlue.cpp
linux/ThisThread.cpp
)
else()
add_host_subdirectory(linux
- linux/AbstractSocket.cpp
linux/Host.cpp
linux/HostInfoLinux.cpp
linux/HostThreadLinux.cpp
Index: source/Core/PluginManager.cpp
===================================================================
--- source/Core/PluginManager.cpp
+++ source/Core/PluginManager.cpp
@@ -2780,6 +2780,93 @@
return NULL;
}
+#pragma mark Socket
+
+struct SocketInstance
+{
+ SocketInstance() :
+ name(),
+ description(),
+ create_callback(nullptr)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ SocketCreateInstance create_callback;
+};
+
+typedef std::vector<SocketInstance> SocketInstances;
+
+static Mutex &
+GetSocketMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static SocketInstances &
+GetSocketInstances ()
+{
+ static SocketInstances g_instances;
+ return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin (const ConstString &name,
+ const char *description,
+ SocketCreateInstance create_callback)
+{
+ if (!create_callback)
+ return false;
+
+ SocketInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetSocketMutex ());
+ GetSocketInstances ().push_back (instance);
+ return true;
+}
+
+bool
+PluginManager::UnregisterPlugin (SocketCreateInstance create_callback)
+{
+ if (!create_callback)
+ return false;
+
+ Mutex::Locker locker (GetSocketMutex ());
+ SocketInstances &instances = GetSocketInstances ();
+
+ auto end = instances.end();
+ for (auto pos = instances.begin(); pos != end; ++pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ return false;
+}
+
+SocketCreateInstance
+PluginManager::GetSocketCreateCallbackForPluginName (const ConstString &name)
+{
+ if (!name)
+ return nullptr;
+
+ Mutex::Locker locker (GetSocketMutex ());
+ for (auto pos: GetSocketInstances ())
+ {
+ if (name == pos.name)
+ return pos.create_callback;
+ }
+ return nullptr;
+}
+
#pragma mark PluginManager
void
Index: lldb.xcodeproj/project.pbxproj
===================================================================
--- lldb.xcodeproj/project.pbxproj
+++ lldb.xcodeproj/project.pbxproj
@@ -111,12 +111,17 @@
256CBDBA1ADD107200BC6CDC /* RegisterContextLinux_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256CBDB61ADD107200BC6CDC /* RegisterContextLinux_arm.cpp */; };
256CBDBC1ADD107200BC6CDC /* RegisterContextLinux_mips64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256CBDB81ADD107200BC6CDC /* RegisterContextLinux_mips64.cpp */; };
256CBDC01ADD11C000BC6CDC /* RegisterContextPOSIX_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256CBDBE1ADD11C000BC6CDC /* RegisterContextPOSIX_arm.cpp */; };
- 2579065C1BD0488100178368 /* TCPSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2579065A1BD0488100178368 /* TCPSocket.cpp */; };
- 2579065D1BD0488100178368 /* UDPSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2579065B1BD0488100178368 /* UDPSocket.cpp */; };
- 2579065F1BD0488D00178368 /* DomainSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2579065E1BD0488D00178368 /* DomainSocket.cpp */; };
257906641BD5AFD000178368 /* Acceptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 257906621BD5AFD000178368 /* Acceptor.cpp */; };
257906651BD5AFD000178368 /* Acceptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 257906631BD5AFD000178368 /* Acceptor.h */; };
257E47171AA56C2000A62F81 /* ModuleCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 257E47151AA56C2000A62F81 /* ModuleCache.cpp */; };
+ 25B4C4611BDEA2CD005B956D /* AbstractSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25B4C4521BDEA2CD005B956D /* AbstractSocket.cpp */; };
+ 25B4C4621BDEA2CD005B956D /* AbstractSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B4C4531BDEA2CD005B956D /* AbstractSocket.h */; };
+ 25B4C4631BDEA2CD005B956D /* DomainSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25B4C4571BDEA2CD005B956D /* DomainSocket.cpp */; };
+ 25B4C4641BDEA2CD005B956D /* DomainSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B4C4581BDEA2CD005B956D /* DomainSocket.h */; };
+ 25B4C4651BDEA2CD005B956D /* TCPSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25B4C45B1BDEA2CD005B956D /* TCPSocket.cpp */; };
+ 25B4C4661BDEA2CD005B956D /* TCPSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B4C45C1BDEA2CD005B956D /* TCPSocket.h */; };
+ 25B4C4671BDEA2CD005B956D /* UDPSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25B4C45F1BDEA2CD005B956D /* UDPSocket.cpp */; };
+ 25B4C4681BDEA2CD005B956D /* UDPSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B4C4601BDEA2CD005B956D /* UDPSocket.h */; };
25EF23781AC09B3700908DF0 /* AdbClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25EF23751AC09AD800908DF0 /* AdbClient.cpp */; };
260157C61885F51C00F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
260157C81885F53100F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
@@ -1231,13 +1236,23 @@
256CBDB91ADD107200BC6CDC /* RegisterContextLinux_mips64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextLinux_mips64.h; path = Utility/RegisterContextLinux_mips64.h; sourceTree = "<group>"; };
256CBDBE1ADD11C000BC6CDC /* RegisterContextPOSIX_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextPOSIX_arm.cpp; path = Utility/RegisterContextPOSIX_arm.cpp; sourceTree = "<group>"; };
256CBDBF1ADD11C000BC6CDC /* RegisterContextPOSIX_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextPOSIX_arm.h; path = Utility/RegisterContextPOSIX_arm.h; sourceTree = "<group>"; };
- 2579065A1BD0488100178368 /* TCPSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TCPSocket.cpp; sourceTree = "<group>"; };
- 2579065B1BD0488100178368 /* UDPSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UDPSocket.cpp; sourceTree = "<group>"; };
- 2579065E1BD0488D00178368 /* DomainSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DomainSocket.cpp; sourceTree = "<group>"; };
257906621BD5AFD000178368 /* Acceptor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Acceptor.cpp; path = "tools/lldb-server/Acceptor.cpp"; sourceTree = "<group>"; };
257906631BD5AFD000178368 /* Acceptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Acceptor.h; path = "tools/lldb-server/Acceptor.h"; sourceTree = "<group>"; };
257E47151AA56C2000A62F81 /* ModuleCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleCache.cpp; path = source/Utility/ModuleCache.cpp; sourceTree = "<group>"; };
257E47161AA56C2000A62F81 /* ModuleCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModuleCache.h; path = source/Utility/ModuleCache.h; sourceTree = "<group>"; };
+ 25B4C4501BDEA2CD005B956D /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
+ 25B4C4521BDEA2CD005B956D /* AbstractSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractSocket.cpp; sourceTree = "<group>"; };
+ 25B4C4531BDEA2CD005B956D /* AbstractSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractSocket.h; sourceTree = "<group>"; };
+ 25B4C4541BDEA2CD005B956D /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
+ 25B4C4561BDEA2CD005B956D /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
+ 25B4C4571BDEA2CD005B956D /* DomainSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DomainSocket.cpp; sourceTree = "<group>"; };
+ 25B4C4581BDEA2CD005B956D /* DomainSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DomainSocket.h; sourceTree = "<group>"; };
+ 25B4C45A1BDEA2CD005B956D /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
+ 25B4C45B1BDEA2CD005B956D /* TCPSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TCPSocket.cpp; sourceTree = "<group>"; };
+ 25B4C45C1BDEA2CD005B956D /* TCPSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCPSocket.h; sourceTree = "<group>"; };
+ 25B4C45E1BDEA2CD005B956D /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
+ 25B4C45F1BDEA2CD005B956D /* UDPSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UDPSocket.cpp; sourceTree = "<group>"; };
+ 25B4C4601BDEA2CD005B956D /* UDPSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UDPSocket.h; sourceTree = "<group>"; };
25EF23751AC09AD800908DF0 /* AdbClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AdbClient.cpp; sourceTree = "<group>"; };
25EF23761AC09AD800908DF0 /* AdbClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdbClient.h; sourceTree = "<group>"; };
260157C41885F4FF00F875CF /* libpanel.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpanel.dylib; path = /usr/lib/libpanel.dylib; sourceTree = "<absolute>"; };
@@ -3119,9 +3134,62 @@
path = FreeBSD;
sourceTree = "<group>";
};
+ 25B4C44F1BDEA2CD005B956D /* Socket */ = {
+ isa = PBXGroup;
+ children = (
+ 25B4C4501BDEA2CD005B956D /* CMakeLists.txt */,
+ 25B4C4511BDEA2CD005B956D /* Linux */,
+ 25B4C4551BDEA2CD005B956D /* POSIX */,
+ 25B4C4591BDEA2CD005B956D /* TCP */,
+ 25B4C45D1BDEA2CD005B956D /* UDP */,
+ );
+ path = Socket;
+ sourceTree = "<group>";
+ };
+ 25B4C4511BDEA2CD005B956D /* Linux */ = {
+ isa = PBXGroup;
+ children = (
+ 25B4C4521BDEA2CD005B956D /* AbstractSocket.cpp */,
+ 25B4C4531BDEA2CD005B956D /* AbstractSocket.h */,
+ 25B4C4541BDEA2CD005B956D /* CMakeLists.txt */,
+ );
+ path = Linux;
+ sourceTree = "<group>";
+ };
+ 25B4C4551BDEA2CD005B956D /* POSIX */ = {
+ isa = PBXGroup;
+ children = (
+ 25B4C4561BDEA2CD005B956D /* CMakeLists.txt */,
+ 25B4C4571BDEA2CD005B956D /* DomainSocket.cpp */,
+ 25B4C4581BDEA2CD005B956D /* DomainSocket.h */,
+ );
+ path = POSIX;
+ sourceTree = "<group>";
+ };
+ 25B4C4591BDEA2CD005B956D /* TCP */ = {
+ isa = PBXGroup;
+ children = (
+ 25B4C45A1BDEA2CD005B956D /* CMakeLists.txt */,
+ 25B4C45B1BDEA2CD005B956D /* TCPSocket.cpp */,
+ 25B4C45C1BDEA2CD005B956D /* TCPSocket.h */,
+ );
+ path = TCP;
+ sourceTree = "<group>";
+ };
+ 25B4C45D1BDEA2CD005B956D /* UDP */ = {
+ isa = PBXGroup;
+ children = (
+ 25B4C45E1BDEA2CD005B956D /* CMakeLists.txt */,
+ 25B4C45F1BDEA2CD005B956D /* UDPSocket.cpp */,
+ 25B4C4601BDEA2CD005B956D /* UDPSocket.h */,
+ );
+ path = UDP;
+ sourceTree = "<group>";
+ };
260C897110F57C5600BB2B04 /* Plugins */ = {
isa = PBXGroup;
children = (
+ 25B4C44F1BDEA2CD005B956D /* Socket */,
8CF02ADD19DCBEC200B14BE0 /* InstrumentationRuntime */,
8C2D6A58197A1FB9006989C9 /* MemoryHistory */,
26DB3E051379E7AD0080DC73 /* ABI */,
@@ -5131,7 +5199,6 @@
3FDFDDC4199D37BE009756A7 /* posix */ = {
isa = PBXGroup;
children = (
- 2579065E1BD0488D00178368 /* DomainSocket.cpp */,
255EFF751AFABA950069F277 /* LockFilePosix.cpp */,
30DED5DC1B4ECB17004CC508 /* MainLoopPosix.cpp */,
AFDFDFD019E34D3400EAE509 /* ConnectionFileDescriptorPosix.cpp */,
@@ -5338,8 +5405,6 @@
69A01E1A1236C5D400C660B5 /* common */ = {
isa = PBXGroup;
children = (
- 2579065A1BD0488100178368 /* TCPSocket.cpp */,
- 2579065B1BD0488100178368 /* UDPSocket.cpp */,
255EFF731AFABA720069F277 /* LockFileBase.cpp */,
250D6AE11A9679270049CC70 /* FileSystem.cpp */,
33E5E8411A672A240024ED68 /* StringConvert.cpp */,
@@ -5783,9 +5848,13 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 25B4C4641BDEA2CD005B956D /* DomainSocket.h in Headers */,
+ 25B4C4661BDEA2CD005B956D /* TCPSocket.h in Headers */,
4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */,
257906651BD5AFD000178368 /* Acceptor.h in Headers */,
260A63171861008E00FECF8E /* IOHandler.h in Headers */,
+ 25B4C4681BDEA2CD005B956D /* UDPSocket.h in Headers */,
+ 25B4C4621BDEA2CD005B956D /* AbstractSocket.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -6302,6 +6371,7 @@
267A47FB1B1411C40021A5BC /* NativeRegisterContext.cpp in Sources */,
2689FFF113353DB600698AC0 /* BreakpointID.cpp in Sources */,
AF77E0A91A033D740096C0EA /* RegisterContextPOSIXCore_powerpc.cpp in Sources */,
+ 25B4C4631BDEA2CD005B956D /* DomainSocket.cpp in Sources */,
2689FFF313353DB600698AC0 /* BreakpointIDList.cpp in Sources */,
2689FFF513353DB600698AC0 /* BreakpointList.cpp in Sources */,
AF77E08F1A033C700096C0EA /* ABISysV_ppc.cpp in Sources */,
@@ -6524,13 +6594,13 @@
2689008D13353E4200698AC0 /* DynamicLoaderMacOSXDYLD.cpp in Sources */,
2689008E13353E4200698AC0 /* DynamicLoaderStatic.cpp in Sources */,
2689009613353E4200698AC0 /* ObjectContainerBSDArchive.cpp in Sources */,
- 2579065D1BD0488100178368 /* UDPSocket.cpp in Sources */,
AE8F624919EF3E1E00326B21 /* OperatingSystemGo.cpp in Sources */,
26BC179A18C7F2B300D2196D /* JITLoaderList.cpp in Sources */,
2689009713353E4200698AC0 /* ObjectContainerUniversalMachO.cpp in Sources */,
2689009813353E4200698AC0 /* ELFHeader.cpp in Sources */,
2689009913353E4200698AC0 /* ObjectFileELF.cpp in Sources */,
2689009A13353E4200698AC0 /* ObjectFileMachO.cpp in Sources */,
+ 25B4C4671BDEA2CD005B956D /* UDPSocket.cpp in Sources */,
2689009B13353E4200698AC0 /* PlatformMacOSX.cpp in Sources */,
2689009C13353E4200698AC0 /* PlatformRemoteiOS.cpp in Sources */,
2689009D13353E4200698AC0 /* GDBRemoteCommunication.cpp in Sources */,
@@ -6594,7 +6664,6 @@
268900D313353E6F00698AC0 /* ClangExternalASTSourceCallbacks.cpp in Sources */,
268900D513353E6F00698AC0 /* CompileUnit.cpp in Sources */,
268900D613353E6F00698AC0 /* Declaration.cpp in Sources */,
- 2579065C1BD0488100178368 /* TCPSocket.cpp in Sources */,
268900D713353E6F00698AC0 /* DWARFCallFrameInfo.cpp in Sources */,
268900D813353E6F00698AC0 /* Function.cpp in Sources */,
268900D913353E6F00698AC0 /* FuncUnwinders.cpp in Sources */,
@@ -6654,7 +6723,6 @@
94B6385D1B8FB178004FE1E4 /* CPlusPlusLanguage.cpp in Sources */,
268900FE13353E6F00698AC0 /* ThreadPlanCallUserExpression.cpp in Sources */,
268900FF13353E6F00698AC0 /* ThreadPlanShouldStopHere.cpp in Sources */,
- 2579065F1BD0488D00178368 /* DomainSocket.cpp in Sources */,
2689010013353E6F00698AC0 /* ThreadPlanStepInstruction.cpp in Sources */,
232CB61B191E00CD00EF39FC /* NativeThreadProtocol.cpp in Sources */,
2689010113353E6F00698AC0 /* ThreadPlanStepOut.cpp in Sources */,
@@ -6790,6 +6858,7 @@
949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */,
B27318421416AC12006039C8 /* WatchpointList.cpp in Sources */,
26CFDCA3186163A4000E63E5 /* Editline.cpp in Sources */,
+ 25B4C4611BDEA2CD005B956D /* AbstractSocket.cpp in Sources */,
26E152261419CAD4007967D0 /* ObjectFilePECOFF.cpp in Sources */,
B2462247141AD37D00F3D409 /* OptionGroupWatchpoint.cpp in Sources */,
94B638631B8FB7F1004FE1E4 /* ObjCPlusPlusLanguage.cpp in Sources */,
@@ -6820,6 +6889,7 @@
26B1EFAE154638AF00E2DAC7 /* DWARFDeclContext.cpp in Sources */,
945215DF17F639EE00521C0B /* ValueObjectPrinter.cpp in Sources */,
260CC64815D0440D002BF2E0 /* OptionValueArgs.cpp in Sources */,
+ 25B4C4651BDEA2CD005B956D /* TCPSocket.cpp in Sources */,
260CC64915D0440D002BF2E0 /* OptionValueArray.cpp in Sources */,
260CC64A15D0440D002BF2E0 /* OptionValueBoolean.cpp in Sources */,
260CC64B15D0440D002BF2E0 /* OptionValueProperties.cpp in Sources */,
Index: include/lldb/lldb-private-interfaces.h
===================================================================
--- include/lldb/lldb-private-interfaces.h
+++ include/lldb/lldb-private-interfaces.h
@@ -52,6 +52,7 @@
typedef lldb::REPLSP (*REPLCreateInstance) (Error &error, lldb::LanguageType language, Debugger *debugger, Target *target, const char *repl_options);
typedef void (*TypeSystemEnumerateSupportedLanguages) (std::set<lldb::LanguageType> &languages_for_types, std::set<lldb::LanguageType> &languages_for_expressions);
typedef void (*REPLEnumerateSupportedLanguages) (std::set<lldb::LanguageType> &languages);
+ typedef Socket* (*SocketCreateInstance) (bool child_processes_inherit, Error &error);
typedef int (*ComparisonFunction)(const void *, const void *);
typedef void (*DebuggerInitializeCallback)(Debugger &debugger);
Index: include/lldb/lldb-forward.h
===================================================================
--- include/lldb/lldb-forward.h
+++ include/lldb/lldb-forward.h
@@ -195,6 +195,7 @@
class SectionLoadHistory;
class SectionLoadList;
class Settings;
+class Socket;
class SourceManager;
class SourceManagerImpl;
class StackFrame;
Index: include/lldb/Host/posix/DomainSocket.h
===================================================================
--- include/lldb/Host/posix/DomainSocket.h
+++ /dev/null
@@ -1,37 +0,0 @@
-//===-- DomainSocket.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_DomainSocket_h_
-#define liblldb_DomainSocket_h_
-
-#include "lldb/Host/Socket.h"
-
-namespace lldb_private
-{
- class DomainSocket: public Socket
- {
- public:
- DomainSocket(bool child_processes_inherit, Error &error);
-
- Error Connect(llvm::StringRef name) override;
- Error Listen(llvm::StringRef name, int backlog) override;
- Error Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket) override;
-
- protected:
- DomainSocket(SocketProtocol protocol, bool child_processes_inherit, Error &error);
-
- virtual size_t GetNameOffset() const;
- virtual void DeleteSocketFile(llvm::StringRef name);
-
- private:
- DomainSocket(NativeSocket socket);
- };
-}
-
-#endif // ifndef liblldb_DomainSocket_h_
Index: include/lldb/Host/linux/AbstractSocket.h
===================================================================
--- include/lldb/Host/linux/AbstractSocket.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===-- AbstractSocket.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_AbstractSocket_h_
-#define liblldb_AbstractSocket_h_
-
-#include "lldb/Host/posix/DomainSocket.h"
-
-namespace lldb_private
-{
- class AbstractSocket: public DomainSocket
- {
- public:
- AbstractSocket(bool child_processes_inherit, Error &error);
-
- protected:
- size_t GetNameOffset() const override;
- void DeleteSocketFile(llvm::StringRef name) override;
- };
-}
-
-#endif // ifndef liblldb_AbstractSocket_h_
Index: include/lldb/Host/common/UDPSocket.h
===================================================================
--- include/lldb/Host/common/UDPSocket.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===-- UDPSocket.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_UDPSocket_h_
-#define liblldb_UDPSocket_h_
-
-#include "lldb/Host/Socket.h"
-
-namespace lldb_private
-{
- class UDPSocket: public Socket
- {
- public:
- static Error Connect(llvm::StringRef name, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket);
-
- private:
- UDPSocket(NativeSocket socket);
- UDPSocket(bool child_processes_inherit, Error &error);
-
- size_t Send(const void *buf, const size_t num_bytes) override;
- Error Connect(llvm::StringRef name) override;
- Error Listen(llvm::StringRef name, int backlog) override;
- Error Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket) override;
-
- SocketAddress m_send_sockaddr;
- };
-}
-
-#endif // ifndef liblldb_UDPSocket_h_
Index: include/lldb/Host/common/TCPSocket.h
===================================================================
--- include/lldb/Host/common/TCPSocket.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- TCPSocket.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_TCPSocket_h_
-#define liblldb_TCPSocket_h_
-
-#include "lldb/Host/Socket.h"
-
-namespace lldb_private
-{
- class TCPSocket: public Socket
- {
- public:
- TCPSocket(NativeSocket socket, bool should_close);
- TCPSocket(bool child_processes_inherit, Error &error);
-
- // returns port number or 0 if error
- uint16_t GetLocalPortNumber () const;
-
- // returns ip address string or empty string if error
- std::string GetLocalIPAddress () const;
-
- // must be connected
- // returns port number or 0 if error
- uint16_t GetRemotePortNumber () const;
-
- // must be connected
- // returns ip address string or empty string if error
- std::string GetRemoteIPAddress () const;
-
- int SetOptionNoDelay();
- int SetOptionReuseAddress();
-
- Error Connect(llvm::StringRef name) override;
- Error Listen(llvm::StringRef name, int backlog) override;
- Error Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&conn_socket) override;
- };
-}
-
-#endif // ifndef liblldb_TCPSocket_h_
Index: include/lldb/Host/Socket.h
===================================================================
--- include/lldb/Host/Socket.h
+++ include/lldb/Host/Socket.h
@@ -10,11 +10,13 @@
#ifndef liblldb_Host_Socket_h_
#define liblldb_Host_Socket_h_
+#include <memory>
#include <string>
#include "lldb/lldb-private.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/PluginInterface.h"
#include "lldb/Host/IOObject.h"
#include "lldb/Host/Predicate.h"
#include "lldb/Host/SocketAddress.h"
@@ -38,7 +40,8 @@
typedef int NativeSocket;
#endif
-class Socket : public IOObject
+class Socket : public IOObject,
+ public PluginInterface
{
public:
typedef enum
@@ -49,10 +52,20 @@
ProtocolUnixAbstract
} SocketProtocol;
+ static const char *TCP;
+ static const char *UDP;
+ static const char *UNIX;
+ static const char *UNIX_ABSTRACT;
+
static const NativeSocket kInvalidSocketValue;
~Socket() override;
+ static std::unique_ptr<Socket> Create(const char* scheme, bool child_processes_inherit, Error& error);
+
+ static void
+ Initialize();
+
virtual Error Connect(llvm::StringRef name) = 0;
virtual Error Listen(llvm::StringRef name, int backlog) = 0;
virtual Error Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket) = 0;
@@ -78,6 +91,7 @@
NativeSocket GetNativeSocket () const { return m_socket; }
SocketProtocol GetSocketProtocol () const { return m_protocol; }
+ virtual const char* GetScheme() const = 0;
Error Read (void *buf, size_t &num_bytes) override;
Error Write (const void *buf, size_t &num_bytes) override;
@@ -95,6 +109,20 @@
int32_t& port,
Error *error_ptr);
+ // returns port number or 0 if error
+ uint16_t GetLocalPortNumber () const;
+
+ // returns ip address string or empty string if error
+ std::string GetLocalIPAddress () const;
+
+ // must be connected
+ // returns port number or 0 if error
+ uint16_t GetRemotePortNumber () const;
+
+ // must be connected
+ // returns ip address string or empty string if error
+ std::string GetRemoteIPAddress () const;
+
protected:
Socket(NativeSocket socket, SocketProtocol protocol, bool should_close);
@@ -108,7 +136,7 @@
SocketProtocol m_protocol;
NativeSocket m_socket;
-};
+ };
} // namespace lldb_private
Index: include/lldb/Core/PluginManager.h
===================================================================
--- include/lldb/Core/PluginManager.h
+++ include/lldb/Core/PluginManager.h
@@ -466,7 +466,21 @@
static REPLEnumerateSupportedLanguages
GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name);
-
+
+ //------------------------------------------------------------------
+ // Socket
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ SocketCreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin (SocketCreateInstance create_callback);
+
+ static SocketCreateInstance
+ GetSocketCreateCallbackForPluginName (const ConstString &name);
+
//------------------------------------------------------------------
// Some plug-ins might register a DebuggerInitializeCallback
// callback when registering the plug-in. After a new Debugger
Index: cmake/LLDBDependencies.cmake
===================================================================
--- cmake/LLDBDependencies.cmake
+++ cmake/LLDBDependencies.cmake
@@ -74,6 +74,8 @@
lldbPluginProcessElfCore
lldbPluginJITLoaderGDB
lldbPluginExpressionParserClang
+ lldbPluginTCPSocket
+ lldbPluginUDPSocket
)
# Windows-only libraries
@@ -91,14 +93,17 @@
list(APPEND LLDB_USED_LIBS
lldbPluginProcessLinux
lldbPluginProcessPOSIX
+ lldbPluginLinuxSocket
+ lldbPluginPOSIXSocket
)
endif ()
# FreeBSD-only libraries
if ( CMAKE_SYSTEM_NAME MATCHES "FreeBSD" )
list(APPEND LLDB_USED_LIBS
lldbPluginProcessFreeBSD
lldbPluginProcessPOSIX
+ lldbPluginPOSIXSocket
)
endif ()
@@ -110,6 +115,7 @@
lldbPluginProcessMachCore
lldbPluginProcessMacOSXKernel
lldbPluginSymbolVendorMacOSX
+ lldbPluginPOSIXSocket
)
endif()
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits