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/Host/File.h"
16 #include "lldb/Interpreter/Args.h"
17 #include "lldb/Target/Platform.h"
18 #include "lldb/Target/Target.h"
19 #include "lldb/Utility/ArchSpec.h"
20 #include "lldb/Utility/Status.h"
22 #include "llvm/Support/FileSystem.h"
27 using namespace lldb_private;
29 //----------------------------------------------------------------------
30 // PlatformConnectOptions
31 //----------------------------------------------------------------------
32 struct PlatformConnectOptions {
33 PlatformConnectOptions(const char *url = NULL)
34 : m_url(), m_rsync_options(), m_rsync_remote_path_prefix(),
35 m_rsync_enabled(false), m_rsync_omit_hostname_from_remote_path(false),
36 m_local_cache_directory() {
41 ~PlatformConnectOptions() {}
44 std::string m_rsync_options;
45 std::string m_rsync_remote_path_prefix;
47 bool m_rsync_omit_hostname_from_remote_path;
48 ConstString m_local_cache_directory;
51 //----------------------------------------------------------------------
52 // PlatformShellCommand
53 //----------------------------------------------------------------------
54 struct PlatformShellCommand {
55 PlatformShellCommand(const char *shell_command = NULL)
56 : m_command(), m_working_dir(), m_status(0), m_signo(0),
57 m_timeout_sec(UINT32_MAX) {
58 if (shell_command && shell_command[0])
59 m_command = shell_command;
62 ~PlatformShellCommand() {}
64 std::string m_command;
65 std::string m_working_dir;
69 uint32_t m_timeout_sec;
71 //----------------------------------------------------------------------
72 // SBPlatformConnectOptions
73 //----------------------------------------------------------------------
74 SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
75 : m_opaque_ptr(new PlatformConnectOptions(url)) {}
77 SBPlatformConnectOptions::SBPlatformConnectOptions(
78 const SBPlatformConnectOptions &rhs)
79 : m_opaque_ptr(new PlatformConnectOptions()) {
80 *m_opaque_ptr = *rhs.m_opaque_ptr;
83 SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
85 void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
86 *m_opaque_ptr = *rhs.m_opaque_ptr;
89 const char *SBPlatformConnectOptions::GetURL() {
90 if (m_opaque_ptr->m_url.empty())
92 return m_opaque_ptr->m_url.c_str();
95 void SBPlatformConnectOptions::SetURL(const char *url) {
97 m_opaque_ptr->m_url = url;
99 m_opaque_ptr->m_url.clear();
102 bool SBPlatformConnectOptions::GetRsyncEnabled() {
103 return m_opaque_ptr->m_rsync_enabled;
106 void SBPlatformConnectOptions::EnableRsync(
107 const char *options, const char *remote_path_prefix,
108 bool omit_hostname_from_remote_path) {
109 m_opaque_ptr->m_rsync_enabled = true;
110 m_opaque_ptr->m_rsync_omit_hostname_from_remote_path =
111 omit_hostname_from_remote_path;
112 if (remote_path_prefix && remote_path_prefix[0])
113 m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
115 m_opaque_ptr->m_rsync_remote_path_prefix.clear();
117 if (options && options[0])
118 m_opaque_ptr->m_rsync_options = options;
120 m_opaque_ptr->m_rsync_options.clear();
123 void SBPlatformConnectOptions::DisableRsync() {
124 m_opaque_ptr->m_rsync_enabled = false;
127 const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
128 return m_opaque_ptr->m_local_cache_directory.GetCString();
131 void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
133 m_opaque_ptr->m_local_cache_directory.SetCString(path);
135 m_opaque_ptr->m_local_cache_directory = ConstString();
138 //----------------------------------------------------------------------
139 // SBPlatformShellCommand
140 //----------------------------------------------------------------------
141 SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
142 : m_opaque_ptr(new PlatformShellCommand(shell_command)) {}
144 SBPlatformShellCommand::SBPlatformShellCommand(
145 const SBPlatformShellCommand &rhs)
146 : m_opaque_ptr(new PlatformShellCommand()) {
147 *m_opaque_ptr = *rhs.m_opaque_ptr;
150 SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
152 void SBPlatformShellCommand::Clear() {
153 m_opaque_ptr->m_output = std::string();
154 m_opaque_ptr->m_status = 0;
155 m_opaque_ptr->m_signo = 0;
158 const char *SBPlatformShellCommand::GetCommand() {
159 if (m_opaque_ptr->m_command.empty())
161 return m_opaque_ptr->m_command.c_str();
164 void SBPlatformShellCommand::SetCommand(const char *shell_command) {
165 if (shell_command && shell_command[0])
166 m_opaque_ptr->m_command = shell_command;
168 m_opaque_ptr->m_command.clear();
171 const char *SBPlatformShellCommand::GetWorkingDirectory() {
172 if (m_opaque_ptr->m_working_dir.empty())
174 return m_opaque_ptr->m_working_dir.c_str();
177 void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
179 m_opaque_ptr->m_working_dir = path;
181 m_opaque_ptr->m_working_dir.clear();
184 uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
185 return m_opaque_ptr->m_timeout_sec;
188 void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
189 m_opaque_ptr->m_timeout_sec = sec;
192 int SBPlatformShellCommand::GetSignal() { return m_opaque_ptr->m_signo; }
194 int SBPlatformShellCommand::GetStatus() { return m_opaque_ptr->m_status; }
196 const char *SBPlatformShellCommand::GetOutput() {
197 if (m_opaque_ptr->m_output.empty())
199 return m_opaque_ptr->m_output.c_str();
202 //----------------------------------------------------------------------
204 //----------------------------------------------------------------------
205 SBPlatform::SBPlatform() : m_opaque_sp() {}
207 SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() {
209 if (platform_name && platform_name[0])
210 m_opaque_sp = Platform::Create(ConstString(platform_name), error);
213 SBPlatform::~SBPlatform() {}
215 bool SBPlatform::IsValid() const { return m_opaque_sp.get() != NULL; }
217 void SBPlatform::Clear() { m_opaque_sp.reset(); }
219 const char *SBPlatform::GetName() {
220 PlatformSP platform_sp(GetSP());
222 return platform_sp->GetName().GetCString();
226 lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
228 void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
229 m_opaque_sp = platform_sp;
232 const char *SBPlatform::GetWorkingDirectory() {
233 PlatformSP platform_sp(GetSP());
235 return platform_sp->GetWorkingDirectory().GetCString();
239 bool SBPlatform::SetWorkingDirectory(const char *path) {
240 PlatformSP platform_sp(GetSP());
243 platform_sp->SetWorkingDirectory(FileSpec{path, false});
245 platform_sp->SetWorkingDirectory(FileSpec{});
251 SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
253 PlatformSP platform_sp(GetSP());
254 if (platform_sp && connect_options.GetURL()) {
257 llvm::StringRef::withNullAsEmpty(connect_options.GetURL()));
258 sb_error.ref() = platform_sp->ConnectRemote(args);
260 sb_error.SetErrorString("invalid platform");
265 void SBPlatform::DisconnectRemote() {
266 PlatformSP platform_sp(GetSP());
268 platform_sp->DisconnectRemote();
271 bool SBPlatform::IsConnected() {
272 PlatformSP platform_sp(GetSP());
274 platform_sp->IsConnected();
278 const char *SBPlatform::GetTriple() {
279 PlatformSP platform_sp(GetSP());
281 ArchSpec arch(platform_sp->GetSystemArchitecture());
282 if (arch.IsValid()) {
283 // Const-ify the string so we don't need to worry about the lifetime of
285 return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
291 const char *SBPlatform::GetOSBuild() {
292 PlatformSP platform_sp(GetSP());
295 if (platform_sp->GetOSBuildString(s)) {
297 // Const-ify the string so we don't need to worry about the lifetime of
299 return ConstString(s.c_str()).GetCString();
306 const char *SBPlatform::GetOSDescription() {
307 PlatformSP platform_sp(GetSP());
310 if (platform_sp->GetOSKernelDescription(s)) {
312 // Const-ify the string so we don't need to worry about the lifetime of
314 return ConstString(s.c_str()).GetCString();
321 const char *SBPlatform::GetHostname() {
322 PlatformSP platform_sp(GetSP());
324 return platform_sp->GetHostname();
328 uint32_t SBPlatform::GetOSMajorVersion() {
329 uint32_t major, minor, update;
330 PlatformSP platform_sp(GetSP());
331 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
336 uint32_t SBPlatform::GetOSMinorVersion() {
337 uint32_t major, minor, update;
338 PlatformSP platform_sp(GetSP());
339 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
344 uint32_t SBPlatform::GetOSUpdateVersion() {
345 uint32_t major, minor, update;
346 PlatformSP platform_sp(GetSP());
347 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
352 SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
354 PlatformSP platform_sp(GetSP());
356 sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
358 sb_error.SetErrorString("invalid platform");
363 SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
364 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
366 uint32_t permissions = src.ref().GetPermissions();
367 if (permissions == 0) {
368 if (llvm::sys::fs::is_directory(src.ref().GetPath()))
369 permissions = eFilePermissionsDirectoryDefault;
371 permissions = eFilePermissionsFileDefault;
374 return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
378 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
379 src.ref().GetPath().c_str());
384 SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
385 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
387 return platform_sp->Install(src.ref(), dst.ref());
390 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
391 src.ref().GetPath().c_str());
396 SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
397 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
398 const char *command = shell_command.GetCommand();
400 return Status("invalid shell command (empty)");
402 const char *working_dir = shell_command.GetWorkingDirectory();
403 if (working_dir == NULL) {
404 working_dir = platform_sp->GetWorkingDirectory().GetCString();
406 shell_command.SetWorkingDirectory(working_dir);
408 return platform_sp->RunShellCommand(
409 command, FileSpec{working_dir, false},
410 &shell_command.m_opaque_ptr->m_status,
411 &shell_command.m_opaque_ptr->m_signo,
412 &shell_command.m_opaque_ptr->m_output,
413 shell_command.m_opaque_ptr->m_timeout_sec);
417 SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
418 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
419 return platform_sp->LaunchProcess(launch_info.ref());
423 SBError SBPlatform::Kill(const lldb::pid_t pid) {
424 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
425 return platform_sp->KillProcess(pid);
429 SBError SBPlatform::ExecuteConnected(
430 const std::function<Status(const lldb::PlatformSP &)> &func) {
432 const auto platform_sp(GetSP());
434 if (platform_sp->IsConnected())
435 sb_error.ref() = func(platform_sp);
437 sb_error.SetErrorString("not connected");
439 sb_error.SetErrorString("invalid platform");
444 SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
446 PlatformSP platform_sp(GetSP());
449 platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions);
451 sb_error.SetErrorString("invalid platform");
456 uint32_t SBPlatform::GetFilePermissions(const char *path) {
457 PlatformSP platform_sp(GetSP());
459 uint32_t file_permissions = 0;
460 platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions);
461 return file_permissions;
466 SBError SBPlatform::SetFilePermissions(const char *path,
467 uint32_t file_permissions) {
469 PlatformSP platform_sp(GetSP());
471 sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false},
474 sb_error.SetErrorString("invalid platform");
479 SBUnixSignals SBPlatform::GetUnixSignals() const {
480 if (auto platform_sp = GetSP())
481 return SBUnixSignals{platform_sp};