Index: include/lldb/Host/posix/ConnectionFileDescriptorPosix.h =================================================================== --- include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -34,6 +34,17 @@ class ConnectionFileDescriptor : public Connection { public: + static const char* LISTEN_SCHEME; + static const char* ACCEPT_SCHEME; + static const char* UNIX_ACCEPT_SCHEME; + static const char* CONNECT_SCHEME; + static const char* TCP_CONNECT_SCHEME; + static const char* UDP_SCHEME; + static const char* UNIX_CONNECT_SCHEME; + static const char* UNIX_ABSTRACT_CONNECT_SCHEME; + static const char* FD_SCHEME; + static const char* FILE_SCHEME; + ConnectionFileDescriptor(bool child_processes_inherit = false); ConnectionFileDescriptor(int fd, bool owns_fd); Index: source/Host/posix/ConnectionFileDescriptorPosix.cpp =================================================================== --- source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -53,6 +53,31 @@ using namespace lldb; using namespace lldb_private; +const char* ConnectionFileDescriptor::LISTEN_SCHEME = "listen"; +const char* ConnectionFileDescriptor::ACCEPT_SCHEME = "accept"; +const char* ConnectionFileDescriptor::UNIX_ACCEPT_SCHEME = "unix-accept"; +const char* ConnectionFileDescriptor::CONNECT_SCHEME = "connect"; +const char* ConnectionFileDescriptor::TCP_CONNECT_SCHEME = "tcp-connect"; +const char* ConnectionFileDescriptor::UDP_SCHEME = "udp"; +const char* ConnectionFileDescriptor::UNIX_CONNECT_SCHEME = "unix-connect"; +const char* ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME = "unix-abstract-connect"; +const char* ConnectionFileDescriptor::FD_SCHEME = "fd"; +const char* ConnectionFileDescriptor::FILE_SCHEME = "file"; + +namespace { + +const char* +GetURLAddress(const char *url, const char *scheme) +{ + const auto prefix = std::string(scheme) + "://"; + if (strstr(url, prefix.c_str()) != url) + return nullptr; + + return url + prefix.size(); +} + +} + ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit) : Connection() , m_pipe() @@ -154,51 +179,51 @@ if (s && s[0]) { - if (strstr(s, "listen://") == s) + const char *addr; + if ((addr = GetURLAddress(s, LISTEN_SCHEME))) { // listen://HOST:PORT - return SocketListenAndAccept(s + strlen("listen://"), error_ptr); + return SocketListenAndAccept(addr, error_ptr); } - else if (strstr(s, "accept://") == s) + else if ((addr = GetURLAddress(s, ACCEPT_SCHEME))) { // unix://SOCKNAME - return NamedSocketAccept(s + strlen("accept://"), error_ptr); + return NamedSocketAccept(addr, error_ptr); } - else if (strstr(s, "unix-accept://") == s) + else if ((addr = GetURLAddress(s, UNIX_ACCEPT_SCHEME))) { // unix://SOCKNAME - return NamedSocketAccept(s + strlen("unix-accept://"), error_ptr); + return NamedSocketAccept(addr, error_ptr); } - else if (strstr(s, "connect://") == s) + else if ((addr = GetURLAddress(s, CONNECT_SCHEME))) { - return ConnectTCP(s + strlen("connect://"), error_ptr); + return ConnectTCP(addr, error_ptr); } - else if (strstr(s, "tcp-connect://") == s) + else if ((addr = GetURLAddress(s, TCP_CONNECT_SCHEME))) { - return ConnectTCP(s + strlen("tcp-connect://"), error_ptr); + return ConnectTCP(addr, error_ptr); } - else if (strstr(s, "udp://") == s) + else if ((addr = GetURLAddress(s, UDP_SCHEME))) { - return ConnectUDP(s + strlen("udp://"), error_ptr); + return ConnectUDP(addr, error_ptr); } - else if (strstr(s, "unix-connect://") == s) + else if ((addr = GetURLAddress(s, UNIX_CONNECT_SCHEME))) { // unix-connect://SOCKNAME - return NamedSocketConnect(s + strlen("unix-connect://"), error_ptr); + return NamedSocketConnect(addr, error_ptr); } - else if (strstr(s, "unix-abstract-connect://") == s) + else if ((addr = GetURLAddress(s, UNIX_ABSTRACT_CONNECT_SCHEME))) { // unix-abstract-connect://SOCKNAME - return UnixAbstractSocketConnect(s + strlen("unix-abstract-connect://"), error_ptr); + return UnixAbstractSocketConnect(addr, error_ptr); } #ifndef LLDB_DISABLE_POSIX - else if (strstr(s, "fd://") == s) + else if ((addr = GetURLAddress(s, FD_SCHEME))) { // Just passing a native file descriptor within this current process // that is already opened (possibly from a service or other source). - s += strlen("fd://"); bool success = false; - int fd = StringConvert::ToSInt32(s, -1, 0, &success); + int fd = StringConvert::ToSInt32(addr, -1, 0, &success); if (success) { @@ -244,21 +269,21 @@ m_read_sp.reset(new File(fd, false)); m_write_sp.reset(new File(fd, false)); } - m_uri.assign(s); + m_uri.assign(addr); return eConnectionStatusSuccess; } } if (error_ptr) - error_ptr->SetErrorStringWithFormat("invalid file descriptor: \"fd://%s\"", s); + error_ptr->SetErrorStringWithFormat("invalid file descriptor: \"%s\"", s); m_read_sp.reset(); m_write_sp.reset(); return eConnectionStatusError; } - else if (strstr(s, "file://") == s) + else if ((addr = GetURLAddress(s, FILE_SCHEME))) { // file:///PATH - const char *path = s + strlen("file://"); + const char *path = addr; int fd = -1; do { Index: source/Plugins/Platform/Android/AdbClient.h =================================================================== --- source/Plugins/Platform/Android/AdbClient.h +++ source/Plugins/Platform/Android/AdbClient.h @@ -33,6 +33,12 @@ class AdbClient { public: + enum UnixSocketNamespace + { + UnixSocketNamespaceAbstract, + UnixSocketNamespaceFileSystem, + }; + using DeviceIDList = std::list; static Error @@ -51,7 +57,9 @@ SetPortForwarding (const uint16_t local_port, const uint16_t remote_port); Error - SetPortForwarding (const uint16_t local_port, const char* remote_socket_name); + SetPortForwarding (const uint16_t local_port, + const char* remote_socket_name, + const UnixSocketNamespace socket_namespace); Error DeletePortForwarding (const uint16_t local_port); Index: source/Plugins/Platform/Android/AdbClient.cpp =================================================================== --- source/Plugins/Platform/Android/AdbClient.cpp +++ source/Plugins/Platform/Android/AdbClient.cpp @@ -50,6 +50,9 @@ // Default mode for pushed files. const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG +const char * kSocketNamespaceAbstract = "localabstract"; +const char * kSocketNamespaceFileSystem = "localfilesystem"; + } // namespace Error @@ -145,10 +148,17 @@ } Error -AdbClient::SetPortForwarding (const uint16_t local_port, const char* remote_socket_name) +AdbClient::SetPortForwarding (const uint16_t local_port, + const char* remote_socket_name, + const UnixSocketNamespace socket_namespace) { char message[PATH_MAX]; - snprintf (message, sizeof (message), "forward:tcp:%d;localfilesystem:%s", local_port, remote_socket_name); + const char * sock_namespace_str = (socket_namespace == UnixSocketNamespaceAbstract) ? + kSocketNamespaceAbstract : kSocketNamespaceFileSystem; + snprintf (message, sizeof (message), "forward:tcp:%d;%s:%s", + local_port, + sock_namespace_str, + remote_socket_name); const auto error = SendDeviceMessage (message); if (error.Fail ()) Index: source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h =================================================================== --- source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h +++ source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h @@ -19,6 +19,10 @@ // Project includes #include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" +#include "llvm/ADT/Optional.h" + +#include "AdbClient.h" + namespace lldb_private { namespace platform_android { @@ -38,6 +42,7 @@ protected: std::string m_device_id; std::map m_port_forwards; + llvm::Optional m_socket_namespace; bool LaunchGDBServer (lldb::pid_t &pid, std::string &connect_url) override; Index: source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp =================================================================== --- source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp +++ source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp @@ -11,7 +11,6 @@ #include "lldb/Core/Error.h" #include "lldb/Core/Log.h" #include "lldb/Host/common/TCPSocket.h" -#include "AdbClient.h" #include "PlatformAndroidRemoteGDBServer.h" #include "Utility/UriParser.h" @@ -27,6 +26,7 @@ ForwardPortWithAdb (const uint16_t local_port, const uint16_t remote_port, const char* remote_socket_name, + const llvm::Optional& socket_namespace, std::string& device_id) { Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); @@ -49,7 +49,11 @@ if (log) log->Printf("Forwarding remote socket \"%s\" to local TCP port %d", remote_socket_name, local_port); - return adb.SetPortForwarding(local_port, remote_socket_name); + + if (!socket_namespace) + return Error("Invalid socket namespace"); + + return adb.SetPortForwarding(local_port, remote_socket_name, *socket_namespace); } static Error @@ -129,6 +133,12 @@ if (host != "localhost") m_device_id = host; + m_socket_namespace.reset(); + if (scheme == ConnectionFileDescriptor::UNIX_CONNECT_SCHEME) + m_socket_namespace = AdbClient::UnixSocketNamespaceFileSystem; + else if (scheme == ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME) + m_socket_namespace = AdbClient::UnixSocketNamespaceAbstract; + std::string connect_url; auto error = MakeConnectURL (g_remote_platform_pid, (remote_port < 0) ? 0 : remote_port, @@ -196,7 +206,11 @@ if (error.Fail()) return error; - error = ForwardPortWithAdb(local_port, remote_port, remote_socket_name, m_device_id); + error = ForwardPortWithAdb(local_port, + remote_port, + remote_socket_name, + m_socket_namespace, + m_device_id); if (error.Success()) { m_port_forwards[pid] = local_port;