1 //===-- SBPlatform.cpp ------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/API/SBPlatform.h"
11 #include "lldb/API/SBError.h"
12 #include "lldb/API/SBFileSpec.h"
13 #include "lldb/API/SBLaunchInfo.h"
14 #include "lldb/API/SBUnixSignals.h"
15 #include "lldb/Core/ArchSpec.h"
16 #include "lldb/Core/Error.h"
17 #include "lldb/Host/File.h"
18 #include "lldb/Interpreter/Args.h"
19 #include "lldb/Target/Platform.h"
20 #include "lldb/Target/Target.h"
25 using namespace lldb_private;
27 //----------------------------------------------------------------------
28 // PlatformConnectOptions
29 //----------------------------------------------------------------------
30 struct PlatformConnectOptions {
31 PlatformConnectOptions(const char *url = NULL)
32 : m_url(), m_rsync_options(), m_rsync_remote_path_prefix(),
33 m_rsync_enabled(false), m_rsync_omit_hostname_from_remote_path(false),
34 m_local_cache_directory() {
39 ~PlatformConnectOptions() {}
42 std::string m_rsync_options;
43 std::string m_rsync_remote_path_prefix;
45 bool m_rsync_omit_hostname_from_remote_path;
46 ConstString m_local_cache_directory;
49 //----------------------------------------------------------------------
50 // PlatformShellCommand
51 //----------------------------------------------------------------------
52 struct PlatformShellCommand {
53 PlatformShellCommand(const char *shell_command = NULL)
54 : m_command(), m_working_dir(), m_status(0), m_signo(0),
55 m_timeout_sec(UINT32_MAX) {
56 if (shell_command && shell_command[0])
57 m_command = shell_command;
60 ~PlatformShellCommand() {}
62 std::string m_command;
63 std::string m_working_dir;
67 uint32_t m_timeout_sec;
69 //----------------------------------------------------------------------
70 // SBPlatformConnectOptions
71 //----------------------------------------------------------------------
72 SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
73 : m_opaque_ptr(new PlatformConnectOptions(url)) {}
75 SBPlatformConnectOptions::SBPlatformConnectOptions(
76 const SBPlatformConnectOptions &rhs)
77 : m_opaque_ptr(new PlatformConnectOptions()) {
78 *m_opaque_ptr = *rhs.m_opaque_ptr;
81 SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
83 void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
84 *m_opaque_ptr = *rhs.m_opaque_ptr;
87 const char *SBPlatformConnectOptions::GetURL() {
88 if (m_opaque_ptr->m_url.empty())
90 return m_opaque_ptr->m_url.c_str();
93 void SBPlatformConnectOptions::SetURL(const char *url) {
95 m_opaque_ptr->m_url = url;
97 m_opaque_ptr->m_url.clear();
100 bool SBPlatformConnectOptions::GetRsyncEnabled() {
101 return m_opaque_ptr->m_rsync_enabled;
104 void SBPlatformConnectOptions::EnableRsync(
105 const char *options, const char *remote_path_prefix,
106 bool omit_hostname_from_remote_path) {
107 m_opaque_ptr->m_rsync_enabled = true;
108 m_opaque_ptr->m_rsync_omit_hostname_from_remote_path =
109 omit_hostname_from_remote_path;
110 if (remote_path_prefix && remote_path_prefix[0])
111 m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
113 m_opaque_ptr->m_rsync_remote_path_prefix.clear();
115 if (options && options[0])
116 m_opaque_ptr->m_rsync_options = options;
118 m_opaque_ptr->m_rsync_options.clear();
121 void SBPlatformConnectOptions::DisableRsync() {
122 m_opaque_ptr->m_rsync_enabled = false;
125 const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
126 return m_opaque_ptr->m_local_cache_directory.GetCString();
129 void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
131 m_opaque_ptr->m_local_cache_directory.SetCString(path);
133 m_opaque_ptr->m_local_cache_directory = ConstString();
136 //----------------------------------------------------------------------
137 // SBPlatformShellCommand
138 //----------------------------------------------------------------------
139 SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
140 : m_opaque_ptr(new PlatformShellCommand(shell_command)) {}
142 SBPlatformShellCommand::SBPlatformShellCommand(
143 const SBPlatformShellCommand &rhs)
144 : m_opaque_ptr(new PlatformShellCommand()) {
145 *m_opaque_ptr = *rhs.m_opaque_ptr;
148 SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
150 void SBPlatformShellCommand::Clear() {
151 m_opaque_ptr->m_output = std::string();
152 m_opaque_ptr->m_status = 0;
153 m_opaque_ptr->m_signo = 0;
156 const char *SBPlatformShellCommand::GetCommand() {
157 if (m_opaque_ptr->m_command.empty())
159 return m_opaque_ptr->m_command.c_str();
162 void SBPlatformShellCommand::SetCommand(const char *shell_command) {
163 if (shell_command && shell_command[0])
164 m_opaque_ptr->m_command = shell_command;
166 m_opaque_ptr->m_command.clear();
169 const char *SBPlatformShellCommand::GetWorkingDirectory() {
170 if (m_opaque_ptr->m_working_dir.empty())
172 return m_opaque_ptr->m_working_dir.c_str();
175 void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
177 m_opaque_ptr->m_working_dir = path;
179 m_opaque_ptr->m_working_dir.clear();
182 uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
183 return m_opaque_ptr->m_timeout_sec;
186 void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
187 m_opaque_ptr->m_timeout_sec = sec;
190 int SBPlatformShellCommand::GetSignal() { return m_opaque_ptr->m_signo; }
192 int SBPlatformShellCommand::GetStatus() { return m_opaque_ptr->m_status; }
194 const char *SBPlatformShellCommand::GetOutput() {
195 if (m_opaque_ptr->m_output.empty())
197 return m_opaque_ptr->m_output.c_str();
200 //----------------------------------------------------------------------
202 //----------------------------------------------------------------------
203 SBPlatform::SBPlatform() : m_opaque_sp() {}
205 SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() {
207 if (platform_name && platform_name[0])
208 m_opaque_sp = Platform::Create(ConstString(platform_name), error);
211 SBPlatform::~SBPlatform() {}
213 bool SBPlatform::IsValid() const { return m_opaque_sp.get() != NULL; }
215 void SBPlatform::Clear() { m_opaque_sp.reset(); }
217 const char *SBPlatform::GetName() {
218 PlatformSP platform_sp(GetSP());
220 return platform_sp->GetName().GetCString();
224 lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
226 void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
227 m_opaque_sp = platform_sp;
230 const char *SBPlatform::GetWorkingDirectory() {
231 PlatformSP platform_sp(GetSP());
233 return platform_sp->GetWorkingDirectory().GetCString();
237 bool SBPlatform::SetWorkingDirectory(const char *path) {
238 PlatformSP platform_sp(GetSP());
241 platform_sp->SetWorkingDirectory(FileSpec{path, false});
243 platform_sp->SetWorkingDirectory(FileSpec{});
249 SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
251 PlatformSP platform_sp(GetSP());
252 if (platform_sp && connect_options.GetURL()) {
255 llvm::StringRef::withNullAsEmpty(connect_options.GetURL()));
256 sb_error.ref() = platform_sp->ConnectRemote(args);
258 sb_error.SetErrorString("invalid platform");
263 void SBPlatform::DisconnectRemote() {
264 PlatformSP platform_sp(GetSP());
266 platform_sp->DisconnectRemote();
269 bool SBPlatform::IsConnected() {
270 PlatformSP platform_sp(GetSP());
272 platform_sp->IsConnected();
276 const char *SBPlatform::GetTriple() {
277 PlatformSP platform_sp(GetSP());
279 ArchSpec arch(platform_sp->GetSystemArchitecture());
280 if (arch.IsValid()) {
281 // Const-ify the string so we don't need to worry about the lifetime of
283 return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
289 const char *SBPlatform::GetOSBuild() {
290 PlatformSP platform_sp(GetSP());
293 if (platform_sp->GetOSBuildString(s)) {
295 // Const-ify the string so we don't need to worry about the lifetime of
297 return ConstString(s.c_str()).GetCString();
304 const char *SBPlatform::GetOSDescription() {
305 PlatformSP platform_sp(GetSP());
308 if (platform_sp->GetOSKernelDescription(s)) {
310 // Const-ify the string so we don't need to worry about the lifetime of
312 return ConstString(s.c_str()).GetCString();
319 const char *SBPlatform::GetHostname() {
320 PlatformSP platform_sp(GetSP());
322 return platform_sp->GetHostname();
326 uint32_t SBPlatform::GetOSMajorVersion() {
327 uint32_t major, minor, update;
328 PlatformSP platform_sp(GetSP());
329 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
334 uint32_t SBPlatform::GetOSMinorVersion() {
335 uint32_t major, minor, update;
336 PlatformSP platform_sp(GetSP());
337 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
342 uint32_t SBPlatform::GetOSUpdateVersion() {
343 uint32_t major, minor, update;
344 PlatformSP platform_sp(GetSP());
345 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
350 SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
352 PlatformSP platform_sp(GetSP());
354 sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
356 sb_error.SetErrorString("invalid platform");
361 SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
362 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
364 uint32_t permissions = src.ref().GetPermissions();
365 if (permissions == 0) {
366 if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory)
367 permissions = eFilePermissionsDirectoryDefault;
369 permissions = eFilePermissionsFileDefault;
372 return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
376 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
377 src.ref().GetPath().c_str());
382 SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
383 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
385 return platform_sp->Install(src.ref(), dst.ref());
388 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
389 src.ref().GetPath().c_str());
394 SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
395 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
396 const char *command = shell_command.GetCommand();
398 return Error("invalid shell command (empty)");
400 const char *working_dir = shell_command.GetWorkingDirectory();
401 if (working_dir == NULL) {
402 working_dir = platform_sp->GetWorkingDirectory().GetCString();
404 shell_command.SetWorkingDirectory(working_dir);
406 return platform_sp->RunShellCommand(
407 command, FileSpec{working_dir, false},
408 &shell_command.m_opaque_ptr->m_status,
409 &shell_command.m_opaque_ptr->m_signo,
410 &shell_command.m_opaque_ptr->m_output,
411 shell_command.m_opaque_ptr->m_timeout_sec);
415 SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
416 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
417 return platform_sp->LaunchProcess(launch_info.ref());
421 SBError SBPlatform::Kill(const lldb::pid_t pid) {
422 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
423 return platform_sp->KillProcess(pid);
427 SBError SBPlatform::ExecuteConnected(
428 const std::function<Error(const lldb::PlatformSP &)> &func) {
430 const auto platform_sp(GetSP());
432 if (platform_sp->IsConnected())
433 sb_error.ref() = func(platform_sp);
435 sb_error.SetErrorString("not connected");
437 sb_error.SetErrorString("invalid platform");
442 SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
444 PlatformSP platform_sp(GetSP());
447 platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions);
449 sb_error.SetErrorString("invalid platform");
454 uint32_t SBPlatform::GetFilePermissions(const char *path) {
455 PlatformSP platform_sp(GetSP());
457 uint32_t file_permissions = 0;
458 platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions);
459 return file_permissions;
464 SBError SBPlatform::SetFilePermissions(const char *path,
465 uint32_t file_permissions) {
467 PlatformSP platform_sp(GetSP());
469 sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false},
472 sb_error.SetErrorString("invalid platform");
477 SBUnixSignals SBPlatform::GetUnixSignals() const {
478 if (auto platform_sp = GetSP())
479 return SBUnixSignals{platform_sp};