blob: 6085cef32064ed167b09578ac67ec3b372900610 [file] [log] [blame]
Greg Claytonfbb76342013-11-20 21:07:01 +00001//===-- SBPlatform.cpp ------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/API/SBPlatform.h"
11#include "lldb/API/SBError.h"
12#include "lldb/API/SBFileSpec.h"
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +000013#include "lldb/API/SBLaunchInfo.h"
Chaoren Lin98d0a4b2015-07-14 01:09:28 +000014#include "lldb/API/SBUnixSignals.h"
Greg Claytonfbb76342013-11-20 21:07:01 +000015#include "lldb/Core/ArchSpec.h"
16#include "lldb/Core/Error.h"
17#include "lldb/Host/File.h"
18#include "lldb/Interpreter/Args.h"
Greg Claytonfbb76342013-11-20 21:07:01 +000019#include "lldb/Target/Platform.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000020#include "lldb/Target/Target.h"
Greg Claytonfbb76342013-11-20 21:07:01 +000021
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +000022#include <functional>
23
Greg Claytonfbb76342013-11-20 21:07:01 +000024using namespace lldb;
25using namespace lldb_private;
26
27//----------------------------------------------------------------------
28// PlatformConnectOptions
29//----------------------------------------------------------------------
30struct PlatformConnectOptions {
Kate Stoneb9c1b512016-09-06 20:57:50 +000031 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() {
35 if (url && url[0])
36 m_url = url;
37 }
Greg Claytonfbb76342013-11-20 21:07:01 +000038
Kate Stoneb9c1b512016-09-06 20:57:50 +000039 ~PlatformConnectOptions() {}
40
41 std::string m_url;
42 std::string m_rsync_options;
43 std::string m_rsync_remote_path_prefix;
44 bool m_rsync_enabled;
45 bool m_rsync_omit_hostname_from_remote_path;
46 ConstString m_local_cache_directory;
Greg Claytonfbb76342013-11-20 21:07:01 +000047};
48
49//----------------------------------------------------------------------
50// PlatformShellCommand
51//----------------------------------------------------------------------
52struct PlatformShellCommand {
Kate Stoneb9c1b512016-09-06 20:57:50 +000053 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;
58 }
59
60 ~PlatformShellCommand() {}
61
62 std::string m_command;
63 std::string m_working_dir;
64 std::string m_output;
65 int m_status;
66 int m_signo;
67 uint32_t m_timeout_sec;
Greg Claytonfbb76342013-11-20 21:07:01 +000068};
69//----------------------------------------------------------------------
70// SBPlatformConnectOptions
71//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000072SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
73 : m_opaque_ptr(new PlatformConnectOptions(url)) {}
74
75SBPlatformConnectOptions::SBPlatformConnectOptions(
76 const SBPlatformConnectOptions &rhs)
77 : m_opaque_ptr(new PlatformConnectOptions()) {
78 *m_opaque_ptr = *rhs.m_opaque_ptr;
Greg Claytonfbb76342013-11-20 21:07:01 +000079}
80
Kate Stoneb9c1b512016-09-06 20:57:50 +000081SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
82
83void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
84 *m_opaque_ptr = *rhs.m_opaque_ptr;
Greg Claytonfbb76342013-11-20 21:07:01 +000085}
86
Kate Stoneb9c1b512016-09-06 20:57:50 +000087const char *SBPlatformConnectOptions::GetURL() {
88 if (m_opaque_ptr->m_url.empty())
89 return NULL;
90 return m_opaque_ptr->m_url.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +000091}
92
Kate Stoneb9c1b512016-09-06 20:57:50 +000093void SBPlatformConnectOptions::SetURL(const char *url) {
94 if (url && url[0])
95 m_opaque_ptr->m_url = url;
96 else
97 m_opaque_ptr->m_url.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +000098}
99
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100bool SBPlatformConnectOptions::GetRsyncEnabled() {
101 return m_opaque_ptr->m_rsync_enabled;
Greg Claytonfbb76342013-11-20 21:07:01 +0000102}
103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104void 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;
112 else
113 m_opaque_ptr->m_rsync_remote_path_prefix.clear();
114
115 if (options && options[0])
116 m_opaque_ptr->m_rsync_options = options;
117 else
118 m_opaque_ptr->m_rsync_options.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +0000119}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120
121void SBPlatformConnectOptions::DisableRsync() {
122 m_opaque_ptr->m_rsync_enabled = false;
Greg Claytonfbb76342013-11-20 21:07:01 +0000123}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124
125const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
126 return m_opaque_ptr->m_local_cache_directory.GetCString();
127}
128
129void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
130 if (path && path[0])
131 m_opaque_ptr->m_local_cache_directory.SetCString(path);
132 else
133 m_opaque_ptr->m_local_cache_directory = ConstString();
Greg Claytonfbb76342013-11-20 21:07:01 +0000134}
135
136//----------------------------------------------------------------------
137// SBPlatformShellCommand
138//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
140 : m_opaque_ptr(new PlatformShellCommand(shell_command)) {}
141
142SBPlatformShellCommand::SBPlatformShellCommand(
143 const SBPlatformShellCommand &rhs)
144 : m_opaque_ptr(new PlatformShellCommand()) {
145 *m_opaque_ptr = *rhs.m_opaque_ptr;
Greg Claytonfbb76342013-11-20 21:07:01 +0000146}
147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
149
150void SBPlatformShellCommand::Clear() {
151 m_opaque_ptr->m_output = std::string();
152 m_opaque_ptr->m_status = 0;
153 m_opaque_ptr->m_signo = 0;
Greg Claytonfbb76342013-11-20 21:07:01 +0000154}
155
Kate Stoneb9c1b512016-09-06 20:57:50 +0000156const char *SBPlatformShellCommand::GetCommand() {
157 if (m_opaque_ptr->m_command.empty())
158 return NULL;
159 return m_opaque_ptr->m_command.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +0000160}
161
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162void SBPlatformShellCommand::SetCommand(const char *shell_command) {
163 if (shell_command && shell_command[0])
164 m_opaque_ptr->m_command = shell_command;
165 else
166 m_opaque_ptr->m_command.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +0000167}
168
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169const char *SBPlatformShellCommand::GetWorkingDirectory() {
170 if (m_opaque_ptr->m_working_dir.empty())
171 return NULL;
172 return m_opaque_ptr->m_working_dir.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +0000173}
174
Kate Stoneb9c1b512016-09-06 20:57:50 +0000175void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
176 if (path && path[0])
177 m_opaque_ptr->m_working_dir = path;
178 else
179 m_opaque_ptr->m_working_dir.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +0000180}
181
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
183 return m_opaque_ptr->m_timeout_sec;
Greg Claytonfbb76342013-11-20 21:07:01 +0000184}
185
Kate Stoneb9c1b512016-09-06 20:57:50 +0000186void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
187 m_opaque_ptr->m_timeout_sec = sec;
Greg Claytonfbb76342013-11-20 21:07:01 +0000188}
189
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190int SBPlatformShellCommand::GetSignal() { return m_opaque_ptr->m_signo; }
Greg Claytonfbb76342013-11-20 21:07:01 +0000191
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192int SBPlatformShellCommand::GetStatus() { return m_opaque_ptr->m_status; }
Greg Claytonfbb76342013-11-20 21:07:01 +0000193
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194const char *SBPlatformShellCommand::GetOutput() {
195 if (m_opaque_ptr->m_output.empty())
196 return NULL;
197 return m_opaque_ptr->m_output.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +0000198}
199
200//----------------------------------------------------------------------
201// SBPlatform
202//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000203SBPlatform::SBPlatform() : m_opaque_sp() {}
204
205SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() {
206 Error error;
207 if (platform_name && platform_name[0])
208 m_opaque_sp = Platform::Create(ConstString(platform_name), error);
Greg Claytonfbb76342013-11-20 21:07:01 +0000209}
210
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211SBPlatform::~SBPlatform() {}
212
213bool SBPlatform::IsValid() const { return m_opaque_sp.get() != NULL; }
214
215void SBPlatform::Clear() { m_opaque_sp.reset(); }
216
217const char *SBPlatform::GetName() {
218 PlatformSP platform_sp(GetSP());
219 if (platform_sp)
220 return platform_sp->GetName().GetCString();
221 return NULL;
222}
223
224lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
225
226void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
227 m_opaque_sp = platform_sp;
228}
229
230const char *SBPlatform::GetWorkingDirectory() {
231 PlatformSP platform_sp(GetSP());
232 if (platform_sp)
233 return platform_sp->GetWorkingDirectory().GetCString();
234 return NULL;
235}
236
237bool SBPlatform::SetWorkingDirectory(const char *path) {
238 PlatformSP platform_sp(GetSP());
239 if (platform_sp) {
240 if (path)
241 platform_sp->SetWorkingDirectory(FileSpec{path, false});
242 else
243 platform_sp->SetWorkingDirectory(FileSpec{});
244 return true;
245 }
246 return false;
247}
248
249SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
250 SBError sb_error;
251 PlatformSP platform_sp(GetSP());
252 if (platform_sp && connect_options.GetURL()) {
253 Args args;
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000254 args.AppendArgument(
255 llvm::StringRef::withNullAsEmpty(connect_options.GetURL()));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000256 sb_error.ref() = platform_sp->ConnectRemote(args);
257 } else {
258 sb_error.SetErrorString("invalid platform");
259 }
260 return sb_error;
261}
262
263void SBPlatform::DisconnectRemote() {
264 PlatformSP platform_sp(GetSP());
265 if (platform_sp)
266 platform_sp->DisconnectRemote();
267}
268
269bool SBPlatform::IsConnected() {
270 PlatformSP platform_sp(GetSP());
271 if (platform_sp)
272 platform_sp->IsConnected();
273 return false;
274}
275
276const char *SBPlatform::GetTriple() {
277 PlatformSP platform_sp(GetSP());
278 if (platform_sp) {
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
282 // the string
283 return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
284 }
285 }
286 return NULL;
287}
288
289const char *SBPlatform::GetOSBuild() {
290 PlatformSP platform_sp(GetSP());
291 if (platform_sp) {
292 std::string s;
293 if (platform_sp->GetOSBuildString(s)) {
294 if (!s.empty()) {
295 // Const-ify the string so we don't need to worry about the lifetime of
296 // the string
297 return ConstString(s.c_str()).GetCString();
298 }
299 }
300 }
301 return NULL;
302}
303
304const char *SBPlatform::GetOSDescription() {
305 PlatformSP platform_sp(GetSP());
306 if (platform_sp) {
307 std::string s;
308 if (platform_sp->GetOSKernelDescription(s)) {
309 if (!s.empty()) {
310 // Const-ify the string so we don't need to worry about the lifetime of
311 // the string
312 return ConstString(s.c_str()).GetCString();
313 }
314 }
315 }
316 return NULL;
317}
318
319const char *SBPlatform::GetHostname() {
320 PlatformSP platform_sp(GetSP());
321 if (platform_sp)
322 return platform_sp->GetHostname();
323 return NULL;
324}
325
326uint32_t SBPlatform::GetOSMajorVersion() {
327 uint32_t major, minor, update;
328 PlatformSP platform_sp(GetSP());
329 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
330 return major;
331 return UINT32_MAX;
332}
333
334uint32_t SBPlatform::GetOSMinorVersion() {
335 uint32_t major, minor, update;
336 PlatformSP platform_sp(GetSP());
337 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
338 return minor;
339 return UINT32_MAX;
340}
341
342uint32_t SBPlatform::GetOSUpdateVersion() {
343 uint32_t major, minor, update;
344 PlatformSP platform_sp(GetSP());
345 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
346 return update;
347 return UINT32_MAX;
348}
349
350SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
351 SBError sb_error;
352 PlatformSP platform_sp(GetSP());
353 if (platform_sp) {
354 sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
355 } else {
356 sb_error.SetErrorString("invalid platform");
357 }
358 return sb_error;
359}
360
361SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
362 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
363 if (src.Exists()) {
364 uint32_t permissions = src.ref().GetPermissions();
365 if (permissions == 0) {
366 if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory)
367 permissions = eFilePermissionsDirectoryDefault;
368 else
369 permissions = eFilePermissionsFileDefault;
370 }
371
372 return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
373 }
374
Greg Claytonfbb76342013-11-20 21:07:01 +0000375 Error error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000376 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
377 src.ref().GetPath().c_str());
378 return error;
379 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000380}
381
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
383 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
384 if (src.Exists())
385 return platform_sp->Install(src.ref(), dst.ref());
386
387 Error error;
388 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
389 src.ref().GetPath().c_str());
390 return error;
391 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000392}
393
Kate Stoneb9c1b512016-09-06 20:57:50 +0000394SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
395 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
396 const char *command = shell_command.GetCommand();
397 if (!command)
398 return Error("invalid shell command (empty)");
Greg Claytonfbb76342013-11-20 21:07:01 +0000399
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400 const char *working_dir = shell_command.GetWorkingDirectory();
401 if (working_dir == NULL) {
402 working_dir = platform_sp->GetWorkingDirectory().GetCString();
403 if (working_dir)
404 shell_command.SetWorkingDirectory(working_dir);
Greg Claytonfbb76342013-11-20 21:07:01 +0000405 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000406 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);
412 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000413}
414
Kate Stoneb9c1b512016-09-06 20:57:50 +0000415SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
416 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
417 return platform_sp->LaunchProcess(launch_info.ref());
418 });
419}
420
421SBError SBPlatform::Kill(const lldb::pid_t pid) {
422 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
423 return platform_sp->KillProcess(pid);
424 });
425}
426
427SBError SBPlatform::ExecuteConnected(
428 const std::function<Error(const lldb::PlatformSP &)> &func) {
429 SBError sb_error;
430 const auto platform_sp(GetSP());
431 if (platform_sp) {
432 if (platform_sp->IsConnected())
433 sb_error.ref() = func(platform_sp);
Greg Claytonfbb76342013-11-20 21:07:01 +0000434 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435 sb_error.SetErrorString("not connected");
436 } else
437 sb_error.SetErrorString("invalid platform");
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000438
439 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000440}
441
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
443 SBError sb_error;
444 PlatformSP platform_sp(GetSP());
445 if (platform_sp) {
446 sb_error.ref() =
447 platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions);
448 } else {
449 sb_error.SetErrorString("invalid platform");
450 }
451 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000452}
453
Kate Stoneb9c1b512016-09-06 20:57:50 +0000454uint32_t SBPlatform::GetFilePermissions(const char *path) {
455 PlatformSP platform_sp(GetSP());
456 if (platform_sp) {
457 uint32_t file_permissions = 0;
458 platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions);
459 return file_permissions;
460 }
461 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +0000462}
463
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464SBError SBPlatform::SetFilePermissions(const char *path,
465 uint32_t file_permissions) {
466 SBError sb_error;
467 PlatformSP platform_sp(GetSP());
468 if (platform_sp) {
469 sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false},
470 file_permissions);
471 } else {
472 sb_error.SetErrorString("invalid platform");
473 }
474 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000475}
476
Kate Stoneb9c1b512016-09-06 20:57:50 +0000477SBUnixSignals SBPlatform::GetUnixSignals() const {
478 if (auto platform_sp = GetSP())
479 return SBUnixSignals{platform_sp};
Chaoren Lin98d0a4b2015-07-14 01:09:28 +0000480
Kate Stoneb9c1b512016-09-06 20:57:50 +0000481 return {};
Chaoren Lin98d0a4b2015-07-14 01:09:28 +0000482}