diff options
author | dim <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
commit | 66b75430a93929d6fc6ed63db14ca28e3ad5b1f6 (patch) | |
tree | 9ed5e1a91f242e2cb5911577356e487a55c01b78 /source/Host/posix | |
parent | 23814158e5384f73c6fa951b66d5f807f9c24a2b (diff) | |
download | FreeBSD-src-66b75430a93929d6fc6ed63db14ca28e3ad5b1f6.zip FreeBSD-src-66b75430a93929d6fc6ed63db14ca28e3ad5b1f6.tar.gz |
Vendor import of stripped lldb trunk r256633:
https://llvm.org/svn/llvm-project/lldb/trunk@256633
Diffstat (limited to 'source/Host/posix')
-rw-r--r-- | source/Host/posix/ConnectionFileDescriptorPosix.cpp | 108 | ||||
-rw-r--r-- | source/Host/posix/DomainSocket.cpp | 133 | ||||
-rw-r--r-- | source/Host/posix/FileSystem.cpp | 57 | ||||
-rw-r--r-- | source/Host/posix/HostInfoPosix.cpp | 21 | ||||
-rw-r--r-- | source/Host/posix/MainLoopPosix.cpp | 6 | ||||
-rw-r--r-- | source/Host/posix/PipePosix.cpp | 10 |
6 files changed, 299 insertions, 36 deletions
diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp index f12f98c..dbbd5a1 100644 --- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -33,6 +33,8 @@ #endif // C++ Includes +#include <sstream> + // Other libraries and framework includes #include "llvm/Support/ErrorHandling.h" #if defined(__APPLE__) @@ -45,11 +47,37 @@ #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" 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() @@ -151,49 +179,51 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr) if (s && s[0]) { - if (strstr(s, "listen://") == s) + const char *addr = nullptr; + 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 ((addr = GetURLAddress(s, CONNECT_SCHEME))) + { + return ConnectTCP(addr, error_ptr); } - else if (strstr(s, "adb://") == s) + else if ((addr = GetURLAddress(s, TCP_CONNECT_SCHEME))) { - int port = -1; - sscanf(s, "adb://%*[^:]:%d", &port); - char host_and_port[sizeof("localhost:65535")]; - snprintf(host_and_port, sizeof(host_and_port), "localhost:%d", port); - return ConnectTCP(host_and_port, error_ptr); + return ConnectTCP(addr, error_ptr); } - else if (strstr(s, "connect://") == s) + else if ((addr = GetURLAddress(s, UDP_SCHEME))) { - return ConnectTCP(s + strlen("connect://"), error_ptr); + return ConnectUDP(addr, error_ptr); } - else if (strstr(s, "tcp-connect://") == s) + else if ((addr = GetURLAddress(s, UNIX_CONNECT_SCHEME))) { - return ConnectTCP(s + strlen("tcp-connect://"), error_ptr); + // unix-connect://SOCKNAME + return NamedSocketConnect(addr, error_ptr); } - else if (strstr(s, "udp://") == s) + else if ((addr = GetURLAddress(s, UNIX_ABSTRACT_CONNECT_SCHEME))) { - return ConnectUDP(s + strlen("udp://"), error_ptr); + // unix-abstract-connect://SOCKNAME + 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) { @@ -223,8 +253,8 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr) // allow us to specify this. For now, we assume we must // assume we don't own it. - std::unique_ptr<Socket> tcp_socket; - tcp_socket.reset(new Socket(fd, Socket::ProtocolTcp, false)); + std::unique_ptr<TCPSocket> tcp_socket; + tcp_socket.reset(new TCPSocket(fd, false)); // Try and get a socket option from this file descriptor to // see if this is a socket and set m_is_socket accordingly. int resuse; @@ -239,21 +269,21 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr) 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 { @@ -763,6 +793,23 @@ ConnectionFileDescriptor::NamedSocketConnect(const char *socket_name, Error *err return eConnectionStatusSuccess; } +lldb::ConnectionStatus +ConnectionFileDescriptor::UnixAbstractSocketConnect(const char *socket_name, Error *error_ptr) +{ + Socket *socket = nullptr; + Error error = Socket::UnixAbstractConnect(socket_name, m_child_processes_inherit, socket); + if (error_ptr) + *error_ptr = error; + m_write_sp.reset(socket); + m_read_sp = m_write_sp; + if (error.Fail()) + { + return eConnectionStatusError; + } + m_uri.assign(socket_name); + return eConnectionStatusSuccess; +} + ConnectionStatus ConnectionFileDescriptor::SocketListenAndAccept(const char *s, Error *error_ptr) { @@ -780,7 +827,7 @@ ConnectionFileDescriptor::SocketListenAndAccept(const char *s, Error *error_ptr) listening_socket_up.reset(socket); socket = nullptr; - error = listening_socket_up->BlockingAccept(s, m_child_processes_inherit, socket); + error = listening_socket_up->Accept(s, m_child_processes_inherit, socket); listening_socket_up.reset(); if (error_ptr) *error_ptr = error; @@ -856,9 +903,12 @@ ConnectionFileDescriptor::SetChildProcessesInherit(bool child_processes_inherit) void ConnectionFileDescriptor::InitializeSocket(Socket* socket) { + assert(socket->GetSocketProtocol() == Socket::ProtocolTcp); + TCPSocket* tcp_socket = static_cast<TCPSocket*>(socket); + m_write_sp.reset(socket); m_read_sp = m_write_sp; StreamString strm; - strm.Printf("connect://%s:%u",socket->GetRemoteIPAddress().c_str(), socket->GetRemotePortNumber()); + strm.Printf("connect://%s:%u",tcp_socket->GetRemoteIPAddress().c_str(), tcp_socket->GetRemotePortNumber()); m_uri.swap(strm.GetString()); } diff --git a/source/Host/posix/DomainSocket.cpp b/source/Host/posix/DomainSocket.cpp new file mode 100644 index 0000000..b4427e3 --- /dev/null +++ b/source/Host/posix/DomainSocket.cpp @@ -0,0 +1,133 @@ +//===-- 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 <stddef.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, + socklen_t& saddr_un_len) +{ + if (name.size() + name_offset > sizeof(saddr_un->sun_path)) + return false; + + memset(saddr_un, 0, sizeof(*saddr_un)); + saddr_un->sun_family = kDomain; + + memcpy(saddr_un->sun_path + name_offset, name.data(), name.size()); + + // For domain sockets we can use SUN_LEN in order to calculate size of + // sockaddr_un, but for abstract sockets we have to calculate size manually + // because of leading null symbol. + if (name_offset == 0) + saddr_un_len = SUN_LEN(saddr_un); + else + saddr_un_len = offsetof(struct sockaddr_un, sun_path) + name_offset + name.size(); + +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) + saddr_un->sun_len = saddr_un_len; +#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; + socklen_t saddr_un_len; + if (!SetSockAddr(name, GetNameOffset(), &saddr_un, saddr_un_len)) + return Error("Failed to set socket address"); + + Error error; + if (::connect(GetNativeSocket(), (struct sockaddr *)&saddr_un, saddr_un_len) < 0) + SetLastError (error); + + return error; +} + +Error +DomainSocket::Listen(llvm::StringRef name, int backlog) +{ + sockaddr_un saddr_un; + socklen_t saddr_un_len; + if (!SetSockAddr(name, GetNameOffset(), &saddr_un, saddr_un_len)) + return Error("Failed to set socket address"); + + DeleteSocketFile(name); + + Error error; + if (::bind(GetNativeSocket(), (struct sockaddr *)&saddr_un, saddr_un_len) == 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}); +} diff --git a/source/Host/posix/FileSystem.cpp b/source/Host/posix/FileSystem.cpp index 5269803..1f2e7db 100644 --- a/source/Host/posix/FileSystem.cpp +++ b/source/Host/posix/FileSystem.cpp @@ -20,6 +20,9 @@ #include <sys/mount.h> #include <linux/magic.h> #endif +#if defined(__NetBSD__) +#include <sys/statvfs.h> +#endif // lldb Includes #include "lldb/Core/Error.h" @@ -29,6 +32,9 @@ using namespace lldb; using namespace lldb_private; +const char * +FileSystem::DEV_NULL = "/dev/null"; + FileSpec::PathSyntax FileSystem::GetNativePathSyntax() { @@ -179,6 +185,16 @@ FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst) return error; } +int +FileSystem::GetHardlinkCount(const FileSpec &file_spec) +{ + struct stat file_stat; + if (::stat(file_spec.GetCString(), &file_stat) == 0) + return file_stat.st_nlink; + + return -1; +} + Error FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) { @@ -213,6 +229,34 @@ FileSystem::Readlink(const FileSpec &src, FileSpec &dst) return error; } +Error +FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) +{ + char resolved_path[PATH_MAX]; + if (!src.GetPath (resolved_path, sizeof (resolved_path))) + { + return Error("Couldn't get the canonical path for %s", src.GetCString()); + } + + char real_path[PATH_MAX + 1]; + if (realpath(resolved_path, real_path) == nullptr) + { + Error err; + err.SetErrorToErrno(); + return err; + } + + dst = FileSpec(real_path, false); + + return Error(); +} + +#if defined(__NetBSD__) +static bool IsLocal(const struct statvfs& info) +{ + return (info.f_flag & MNT_LOCAL) != 0; +} +#else static bool IsLocal(const struct statfs& info) { #ifdef __linux__ @@ -230,7 +274,19 @@ static bool IsLocal(const struct statfs& info) return (info.f_flags & MNT_LOCAL) != 0; #endif } +#endif +#if defined(__NetBSD__) +bool +FileSystem::IsLocal(const FileSpec &spec) +{ + struct statvfs statfs_info; + std::string path (spec.GetPath()); + if (statvfs(path.c_str(), &statfs_info) == 0) + return ::IsLocal(statfs_info); + return false; +} +#else bool FileSystem::IsLocal(const FileSpec &spec) { @@ -240,3 +296,4 @@ FileSystem::IsLocal(const FileSpec &spec) return ::IsLocal(statfs_info); return false; } +#endif diff --git a/source/Host/posix/HostInfoPosix.cpp b/source/Host/posix/HostInfoPosix.cpp index c04db71..cfdbf56 100644 --- a/source/Host/posix/HostInfoPosix.cpp +++ b/source/Host/posix/HostInfoPosix.cpp @@ -7,7 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "lldb/lldb-python.h" +#if !defined(LLDB_DISABLE_PYTHON) +#include "Plugins/ScriptInterpreter/Python/lldb-python.h" +#endif + #include "lldb/Core/Log.h" #include "lldb/Host/posix/HostInfoPosix.h" @@ -19,6 +22,7 @@ #include <mutex> #include <netdb.h> #include <pwd.h> +#include <stdlib.h> #include <sys/types.h> #include <unistd.h> @@ -211,16 +215,29 @@ HostInfoPosix::ComputePythonDirectory(FileSpec &file_spec) char raw_path[PATH_MAX]; lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); +#if defined(LLDB_PYTHON_RELATIVE_LIBDIR) + // Build the path by backing out of the lib dir, then building + // with whatever the real python interpreter uses. (e.g. lib + // for most, lib64 on RHEL x86_64). + char python_path[PATH_MAX]; + ::snprintf(python_path, sizeof(python_path), "%s/../%s", raw_path, LLDB_PYTHON_RELATIVE_LIBDIR); + + char final_path[PATH_MAX]; + realpath(python_path, final_path); + file_spec.GetDirectory().SetCString(final_path); + + return true; +#else llvm::SmallString<256> python_version_dir; llvm::raw_svector_ostream os(python_version_dir); os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; - os.flush(); // We may get our string truncated. Should we protect this with an assert? ::strncat(raw_path, python_version_dir.c_str(), sizeof(raw_path) - strlen(raw_path) - 1); file_spec.GetDirectory().SetCString(raw_path); return true; +#endif #else return false; #endif diff --git a/source/Host/posix/MainLoopPosix.cpp b/source/Host/posix/MainLoopPosix.cpp index cb213b9..897f2d1 100644 --- a/source/Host/posix/MainLoopPosix.cpp +++ b/source/Host/posix/MainLoopPosix.cpp @@ -94,10 +94,10 @@ MainLoopPosix::RegisterSignal(int signo, const Callback &callback, Error &error) } void -MainLoopPosix::UnregisterReadObject(const lldb::IOObjectSP &object_sp) +MainLoopPosix::UnregisterReadObject(IOObject::WaitableHandle handle) { - bool erased = m_read_fds.erase(object_sp->GetWaitableHandle()); - (void) erased; + bool erased = m_read_fds.erase(handle); + UNUSED_IF_ASSERT_DISABLED(erased); assert(erased); } diff --git a/source/Host/posix/PipePosix.cpp b/source/Host/posix/PipePosix.cpp index 0ed319f..353faae 100644 --- a/source/Host/posix/PipePosix.cpp +++ b/source/Host/posix/PipePosix.cpp @@ -13,6 +13,12 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Support/FileSystem.h" +#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)) +#ifndef _GLIBCXX_USE_NANOSLEEP +#define _GLIBCXX_USE_NANOSLEEP +#endif +#endif + #include <functional> #include <thread> @@ -30,9 +36,9 @@ int PipePosix::kInvalidDescriptor = -1; enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE -// pipe2 is supported by Linux, FreeBSD v10 and higher. +// pipe2 is supported by a limited set of platforms // TODO: Add more platforms that support pipe2. -#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 10) +#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 10) || defined(__NetBSD__) #define PIPE2_SUPPORTED 1 #else #define PIPE2_SUPPORTED 0 |