//===-- SBPlatform.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/API/SBPlatform.h" #include "lldb/API/SBError.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBLaunchInfo.h" #include "lldb/API/SBUnixSignals.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/Error.h" #include "lldb/Host/File.h" #include "lldb/Interpreter/Args.h" #include "lldb/Target/Target.h" #include "lldb/Target/Platform.h" #include using namespace lldb; using namespace lldb_private; //---------------------------------------------------------------------- // PlatformConnectOptions //---------------------------------------------------------------------- struct PlatformConnectOptions { PlatformConnectOptions(const char *url = NULL) : m_url(), m_rsync_options(), m_rsync_remote_path_prefix(), m_rsync_enabled(false), m_rsync_omit_hostname_from_remote_path(false), m_local_cache_directory () { if (url && url[0]) m_url = url; } ~PlatformConnectOptions() { } std::string m_url; std::string m_rsync_options; std::string m_rsync_remote_path_prefix; bool m_rsync_enabled; bool m_rsync_omit_hostname_from_remote_path; ConstString m_local_cache_directory; }; //---------------------------------------------------------------------- // PlatformShellCommand //---------------------------------------------------------------------- struct PlatformShellCommand { PlatformShellCommand(const char *shell_command = NULL) : m_command(), m_working_dir(), m_status(0), m_signo(0), m_timeout_sec(UINT32_MAX) { if (shell_command && shell_command[0]) m_command = shell_command; } ~PlatformShellCommand() { } std::string m_command; std::string m_working_dir; std::string m_output; int m_status; int m_signo; uint32_t m_timeout_sec; }; //---------------------------------------------------------------------- // SBPlatformConnectOptions //---------------------------------------------------------------------- SBPlatformConnectOptions::SBPlatformConnectOptions (const char *url) : m_opaque_ptr(new PlatformConnectOptions(url)) { } SBPlatformConnectOptions::SBPlatformConnectOptions(const SBPlatformConnectOptions &rhs) : m_opaque_ptr(new PlatformConnectOptions()) { *m_opaque_ptr = *rhs.m_opaque_ptr; } SBPlatformConnectOptions::~SBPlatformConnectOptions () { delete m_opaque_ptr; } void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) { *m_opaque_ptr = *rhs.m_opaque_ptr; } const char * SBPlatformConnectOptions::GetURL() { if (m_opaque_ptr->m_url.empty()) return NULL; return m_opaque_ptr->m_url.c_str(); } void SBPlatformConnectOptions::SetURL(const char *url) { if (url && url[0]) m_opaque_ptr->m_url = url; else m_opaque_ptr->m_url.clear(); } bool SBPlatformConnectOptions::GetRsyncEnabled() { return m_opaque_ptr->m_rsync_enabled; } void SBPlatformConnectOptions::EnableRsync (const char *options, const char *remote_path_prefix, bool omit_hostname_from_remote_path) { m_opaque_ptr->m_rsync_enabled = true; m_opaque_ptr->m_rsync_omit_hostname_from_remote_path = omit_hostname_from_remote_path; if (remote_path_prefix && remote_path_prefix[0]) m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix; else m_opaque_ptr->m_rsync_remote_path_prefix.clear(); if (options && options[0]) m_opaque_ptr->m_rsync_options = options; else m_opaque_ptr->m_rsync_options.clear(); } void SBPlatformConnectOptions::DisableRsync () { m_opaque_ptr->m_rsync_enabled = false; } const char * SBPlatformConnectOptions::GetLocalCacheDirectory() { return m_opaque_ptr->m_local_cache_directory.GetCString(); } void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) { if (path && path[0]) m_opaque_ptr->m_local_cache_directory.SetCString(path); else m_opaque_ptr->m_local_cache_directory = ConstString(); } //---------------------------------------------------------------------- // SBPlatformShellCommand //---------------------------------------------------------------------- SBPlatformShellCommand::SBPlatformShellCommand (const char *shell_command) : m_opaque_ptr(new PlatformShellCommand(shell_command)) { } SBPlatformShellCommand::SBPlatformShellCommand (const SBPlatformShellCommand &rhs) : m_opaque_ptr(new PlatformShellCommand()) { *m_opaque_ptr = *rhs.m_opaque_ptr; } SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; } void SBPlatformShellCommand::Clear() { m_opaque_ptr->m_output = std::string(); m_opaque_ptr->m_status = 0; m_opaque_ptr->m_signo = 0; } const char * SBPlatformShellCommand::GetCommand() { if (m_opaque_ptr->m_command.empty()) return NULL; return m_opaque_ptr->m_command.c_str(); } void SBPlatformShellCommand::SetCommand(const char *shell_command) { if (shell_command && shell_command[0]) m_opaque_ptr->m_command = shell_command; else m_opaque_ptr->m_command.clear(); } const char * SBPlatformShellCommand::GetWorkingDirectory () { if (m_opaque_ptr->m_working_dir.empty()) return NULL; return m_opaque_ptr->m_working_dir.c_str(); } void SBPlatformShellCommand::SetWorkingDirectory (const char *path) { if (path && path[0]) m_opaque_ptr->m_working_dir = path; else m_opaque_ptr->m_working_dir.clear(); } uint32_t SBPlatformShellCommand::GetTimeoutSeconds () { return m_opaque_ptr->m_timeout_sec; } void SBPlatformShellCommand::SetTimeoutSeconds (uint32_t sec) { m_opaque_ptr->m_timeout_sec = sec; } int SBPlatformShellCommand::GetSignal () { return m_opaque_ptr->m_signo; } int SBPlatformShellCommand::GetStatus () { return m_opaque_ptr->m_status; } const char * SBPlatformShellCommand::GetOutput () { if (m_opaque_ptr->m_output.empty()) return NULL; return m_opaque_ptr->m_output.c_str(); } //---------------------------------------------------------------------- // SBPlatform //---------------------------------------------------------------------- SBPlatform::SBPlatform () : m_opaque_sp () { } SBPlatform::SBPlatform (const char *platform_name) : m_opaque_sp () { Error error; if (platform_name && platform_name[0]) m_opaque_sp = Platform::Create (ConstString(platform_name), error); } SBPlatform::~SBPlatform() { } bool SBPlatform::IsValid () const { return m_opaque_sp.get() != NULL; } void SBPlatform::Clear () { m_opaque_sp.reset(); } const char * SBPlatform::GetName () { PlatformSP platform_sp(GetSP()); if (platform_sp) return platform_sp->GetName().GetCString(); return NULL; } lldb::PlatformSP SBPlatform::GetSP () const { return m_opaque_sp; } void SBPlatform::SetSP (const lldb::PlatformSP& platform_sp) { m_opaque_sp = platform_sp; } const char * SBPlatform::GetWorkingDirectory() { PlatformSP platform_sp(GetSP()); if (platform_sp) return platform_sp->GetWorkingDirectory().GetCString(); return NULL; } bool SBPlatform::SetWorkingDirectory(const char *path) { PlatformSP platform_sp(GetSP()); if (platform_sp) { if (path) platform_sp->SetWorkingDirectory(FileSpec{path, false}); else platform_sp->SetWorkingDirectory(FileSpec{}); return true; } return false; } SBError SBPlatform::ConnectRemote (SBPlatformConnectOptions &connect_options) { SBError sb_error; PlatformSP platform_sp(GetSP()); if (platform_sp && connect_options.GetURL()) { Args args; args.AppendArgument(connect_options.GetURL()); sb_error.ref() = platform_sp->ConnectRemote(args); } else { sb_error.SetErrorString("invalid platform"); } return sb_error; } void SBPlatform::DisconnectRemote () { PlatformSP platform_sp(GetSP()); if (platform_sp) platform_sp->DisconnectRemote(); } bool SBPlatform::IsConnected() { PlatformSP platform_sp(GetSP()); if (platform_sp) platform_sp->IsConnected(); return false; } const char * SBPlatform::GetTriple() { PlatformSP platform_sp(GetSP()); if (platform_sp) { ArchSpec arch(platform_sp->GetSystemArchitecture()); if (arch.IsValid()) { // Const-ify the string so we don't need to worry about the lifetime of the string return ConstString(arch.GetTriple().getTriple().c_str()).GetCString(); } } return NULL; } const char * SBPlatform::GetOSBuild() { PlatformSP platform_sp(GetSP()); if (platform_sp) { std::string s; if (platform_sp->GetOSBuildString(s)) { if (!s.empty()) { // Const-ify the string so we don't need to worry about the lifetime of the string return ConstString(s.c_str()).GetCString(); } } } return NULL; } const char * SBPlatform::GetOSDescription() { PlatformSP platform_sp(GetSP()); if (platform_sp) { std::string s; if (platform_sp->GetOSKernelDescription(s)) { if (!s.empty()) { // Const-ify the string so we don't need to worry about the lifetime of the string return ConstString(s.c_str()).GetCString(); } } } return NULL; } const char * SBPlatform::GetHostname () { PlatformSP platform_sp(GetSP()); if (platform_sp) return platform_sp->GetHostname(); return NULL; } uint32_t SBPlatform::GetOSMajorVersion () { uint32_t major, minor, update; PlatformSP platform_sp(GetSP()); if (platform_sp && platform_sp->GetOSVersion(major, minor, update)) return major; return UINT32_MAX; } uint32_t SBPlatform::GetOSMinorVersion () { uint32_t major, minor, update; PlatformSP platform_sp(GetSP()); if (platform_sp && platform_sp->GetOSVersion(major, minor, update)) return minor; return UINT32_MAX; } uint32_t SBPlatform::GetOSUpdateVersion () { uint32_t major, minor, update; PlatformSP platform_sp(GetSP()); if (platform_sp && platform_sp->GetOSVersion(major, minor, update)) return update; return UINT32_MAX; } SBError SBPlatform::Get (SBFileSpec &src, SBFileSpec &dst) { SBError sb_error; PlatformSP platform_sp(GetSP()); if (platform_sp) { sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref()); } else { sb_error.SetErrorString("invalid platform"); } return sb_error; } SBError SBPlatform::Put (SBFileSpec &src, SBFileSpec &dst) { return ExecuteConnected( [&](const lldb::PlatformSP& platform_sp) { if (src.Exists()) { uint32_t permissions = src.ref().GetPermissions(); if (permissions == 0) { if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory) permissions = eFilePermissionsDirectoryDefault; else permissions = eFilePermissionsFileDefault; } return platform_sp->PutFile(src.ref(), dst.ref(), permissions); } Error error; error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str()); return error; }); } SBError SBPlatform::Install (SBFileSpec &src, SBFileSpec &dst) { return ExecuteConnected( [&](const lldb::PlatformSP& platform_sp) { if (src.Exists()) return platform_sp->Install(src.ref(), dst.ref()); Error error; error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str()); return error; }); } SBError SBPlatform::Run (SBPlatformShellCommand &shell_command) { return ExecuteConnected( [&](const lldb::PlatformSP& platform_sp) { const char *command = shell_command.GetCommand(); if (!command) return Error("invalid shell command (empty)"); const char *working_dir = shell_command.GetWorkingDirectory(); if (working_dir == NULL) { working_dir = platform_sp->GetWorkingDirectory().GetCString(); if (working_dir) shell_command.SetWorkingDirectory(working_dir); } return platform_sp->RunShellCommand(command, FileSpec{working_dir, false}, &shell_command.m_opaque_ptr->m_status, &shell_command.m_opaque_ptr->m_signo, &shell_command.m_opaque_ptr->m_output, shell_command.m_opaque_ptr->m_timeout_sec); }); } SBError SBPlatform::Launch (SBLaunchInfo &launch_info) { return ExecuteConnected( [&](const lldb::PlatformSP& platform_sp) { return platform_sp->LaunchProcess(launch_info.ref()); }); } SBError SBPlatform::Kill (const lldb::pid_t pid) { return ExecuteConnected( [&](const lldb::PlatformSP& platform_sp) { return platform_sp->KillProcess(pid); }); } SBError SBPlatform::ExecuteConnected (const std::function& func) { SBError sb_error; const auto platform_sp(GetSP()); if (platform_sp) { if (platform_sp->IsConnected()) sb_error.ref() = func(platform_sp); else sb_error.SetErrorString("not connected"); } else sb_error.SetErrorString("invalid platform"); return sb_error; } SBError SBPlatform::MakeDirectory (const char *path, uint32_t file_permissions) { SBError sb_error; PlatformSP platform_sp(GetSP()); if (platform_sp) { sb_error.ref() = platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions); } else { sb_error.SetErrorString("invalid platform"); } return sb_error; } uint32_t SBPlatform::GetFilePermissions (const char *path) { PlatformSP platform_sp(GetSP()); if (platform_sp) { uint32_t file_permissions = 0; platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions); return file_permissions; } return 0; } SBError SBPlatform::SetFilePermissions (const char *path, uint32_t file_permissions) { SBError sb_error; PlatformSP platform_sp(GetSP()); if (platform_sp) { sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false}, file_permissions); } else { sb_error.SetErrorString("invalid platform"); } return sb_error; } SBUnixSignals SBPlatform::GetUnixSignals() const { if (auto platform_sp = GetSP()) return SBUnixSignals{platform_sp}; return {}; }