summaryrefslogtreecommitdiffstats
path: root/source/Host/posix
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-12-30 11:55:28 +0000
committerdim <dim@FreeBSD.org>2015-12-30 11:55:28 +0000
commit66b75430a93929d6fc6ed63db14ca28e3ad5b1f6 (patch)
tree9ed5e1a91f242e2cb5911577356e487a55c01b78 /source/Host/posix
parent23814158e5384f73c6fa951b66d5f807f9c24a2b (diff)
downloadFreeBSD-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.cpp108
-rw-r--r--source/Host/posix/DomainSocket.cpp133
-rw-r--r--source/Host/posix/FileSystem.cpp57
-rw-r--r--source/Host/posix/HostInfoPosix.cpp21
-rw-r--r--source/Host/posix/MainLoopPosix.cpp6
-rw-r--r--source/Host/posix/PipePosix.cpp10
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
OpenPOWER on IntegriCloud