llvm-project/lldb/source/API/SBPlatform.cpp

633 lines
15 KiB
C++

//===-- 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/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"
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::move(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;
m_opaque_sp = Platform::Create (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(ConstString(path));
else
platform_sp->SetWorkingDirectory(ConstString());
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->GetRemoteSystemArchitecture());
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)
{
SBError sb_error;
PlatformSP platform_sp(GetSP());
if (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;
}
sb_error.ref() = platform_sp->PutFile(src.ref(),
dst.ref(),
permissions);
}
else
{
sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
}
}
else
{
sb_error.SetErrorString("invalid platform");
}
return sb_error;
}
SBError
SBPlatform::Install (SBFileSpec &src,
SBFileSpec &dst)
{
SBError sb_error;
PlatformSP platform_sp(GetSP());
if (platform_sp)
{
if (src.Exists())
{
sb_error.ref() = platform_sp->Install(src.ref(), dst.ref());
}
else
{
sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
}
}
else
{
sb_error.SetErrorString("invalid platform");
}
return sb_error;
}
SBError
SBPlatform::Run (SBPlatformShellCommand &shell_command)
{
SBError sb_error;
PlatformSP platform_sp(GetSP());
if (platform_sp)
{
if (platform_sp->IsConnected())
{
const char *command = shell_command.GetCommand();
if (command)
{
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);
}
sb_error.ref() = platform_sp->RunShellCommand(command,
working_dir,
&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);
}
else
{
sb_error.SetErrorString("invalid shell command (empty)");
}
}
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(path, 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(path, 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(path, file_permissions);
}
else
{
sb_error.SetErrorString("invalid platform");
}
return sb_error;
}