blob: d559a66070f519ceeb9a2ea3a0ef63f00b7759d5 [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/Host/File.h"
Greg Claytonfbb76342013-11-20 21:07:01 +000016#include "lldb/Target/Platform.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000017#include "lldb/Target/Target.h"
Pavel Labath5f19b902017-11-13 16:16:33 +000018#include "lldb/Utility/ArchSpec.h"
Pavel Labath145d95c2018-04-17 18:53:35 +000019#include "lldb/Utility/Args.h"
Zachary Turner97206d52017-05-12 04:51:55 +000020#include "lldb/Utility/Status.h"
Greg Claytonfbb76342013-11-20 21:07:01 +000021
Zachary Turner7d86ee52017-03-08 17:56:08 +000022#include "llvm/Support/FileSystem.h"
23
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +000024#include <functional>
25
Greg Claytonfbb76342013-11-20 21:07:01 +000026using namespace lldb;
27using namespace lldb_private;
28
29//----------------------------------------------------------------------
30// PlatformConnectOptions
31//----------------------------------------------------------------------
32struct PlatformConnectOptions {
Kate Stoneb9c1b512016-09-06 20:57:50 +000033 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() {
37 if (url && url[0])
38 m_url = url;
39 }
Greg Claytonfbb76342013-11-20 21:07:01 +000040
Kate Stoneb9c1b512016-09-06 20:57:50 +000041 ~PlatformConnectOptions() {}
42
43 std::string m_url;
44 std::string m_rsync_options;
45 std::string m_rsync_remote_path_prefix;
46 bool m_rsync_enabled;
47 bool m_rsync_omit_hostname_from_remote_path;
48 ConstString m_local_cache_directory;
Greg Claytonfbb76342013-11-20 21:07:01 +000049};
50
51//----------------------------------------------------------------------
52// PlatformShellCommand
53//----------------------------------------------------------------------
54struct PlatformShellCommand {
Kate Stoneb9c1b512016-09-06 20:57:50 +000055 PlatformShellCommand(const char *shell_command = NULL)
Pavel Labath19dd1a02018-05-10 10:46:03 +000056 : m_command(), m_working_dir(), m_status(0), m_signo(0) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000057 if (shell_command && shell_command[0])
58 m_command = shell_command;
59 }
60
61 ~PlatformShellCommand() {}
62
63 std::string m_command;
64 std::string m_working_dir;
65 std::string m_output;
66 int m_status;
67 int m_signo;
Pavel Labath19dd1a02018-05-10 10:46:03 +000068 Timeout<std::ratio<1>> m_timeout = llvm::None;
Greg Claytonfbb76342013-11-20 21:07:01 +000069};
70//----------------------------------------------------------------------
71// SBPlatformConnectOptions
72//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000073SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
74 : m_opaque_ptr(new PlatformConnectOptions(url)) {}
75
76SBPlatformConnectOptions::SBPlatformConnectOptions(
77 const SBPlatformConnectOptions &rhs)
78 : m_opaque_ptr(new PlatformConnectOptions()) {
79 *m_opaque_ptr = *rhs.m_opaque_ptr;
Greg Claytonfbb76342013-11-20 21:07:01 +000080}
81
Kate Stoneb9c1b512016-09-06 20:57:50 +000082SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
83
84void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
85 *m_opaque_ptr = *rhs.m_opaque_ptr;
Greg Claytonfbb76342013-11-20 21:07:01 +000086}
87
Kate Stoneb9c1b512016-09-06 20:57:50 +000088const char *SBPlatformConnectOptions::GetURL() {
89 if (m_opaque_ptr->m_url.empty())
90 return NULL;
91 return m_opaque_ptr->m_url.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +000092}
93
Kate Stoneb9c1b512016-09-06 20:57:50 +000094void SBPlatformConnectOptions::SetURL(const char *url) {
95 if (url && url[0])
96 m_opaque_ptr->m_url = url;
97 else
98 m_opaque_ptr->m_url.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +000099}
100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101bool SBPlatformConnectOptions::GetRsyncEnabled() {
102 return m_opaque_ptr->m_rsync_enabled;
Greg Claytonfbb76342013-11-20 21:07:01 +0000103}
104
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105void SBPlatformConnectOptions::EnableRsync(
106 const char *options, const char *remote_path_prefix,
107 bool omit_hostname_from_remote_path) {
108 m_opaque_ptr->m_rsync_enabled = true;
109 m_opaque_ptr->m_rsync_omit_hostname_from_remote_path =
110 omit_hostname_from_remote_path;
111 if (remote_path_prefix && remote_path_prefix[0])
112 m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
113 else
114 m_opaque_ptr->m_rsync_remote_path_prefix.clear();
115
116 if (options && options[0])
117 m_opaque_ptr->m_rsync_options = options;
118 else
119 m_opaque_ptr->m_rsync_options.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +0000120}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121
122void SBPlatformConnectOptions::DisableRsync() {
123 m_opaque_ptr->m_rsync_enabled = false;
Greg Claytonfbb76342013-11-20 21:07:01 +0000124}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125
126const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
127 return m_opaque_ptr->m_local_cache_directory.GetCString();
128}
129
130void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
131 if (path && path[0])
132 m_opaque_ptr->m_local_cache_directory.SetCString(path);
133 else
134 m_opaque_ptr->m_local_cache_directory = ConstString();
Greg Claytonfbb76342013-11-20 21:07:01 +0000135}
136
137//----------------------------------------------------------------------
138// SBPlatformShellCommand
139//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
141 : m_opaque_ptr(new PlatformShellCommand(shell_command)) {}
142
143SBPlatformShellCommand::SBPlatformShellCommand(
144 const SBPlatformShellCommand &rhs)
145 : m_opaque_ptr(new PlatformShellCommand()) {
146 *m_opaque_ptr = *rhs.m_opaque_ptr;
Greg Claytonfbb76342013-11-20 21:07:01 +0000147}
148
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
150
151void SBPlatformShellCommand::Clear() {
152 m_opaque_ptr->m_output = std::string();
153 m_opaque_ptr->m_status = 0;
154 m_opaque_ptr->m_signo = 0;
Greg Claytonfbb76342013-11-20 21:07:01 +0000155}
156
Kate Stoneb9c1b512016-09-06 20:57:50 +0000157const char *SBPlatformShellCommand::GetCommand() {
158 if (m_opaque_ptr->m_command.empty())
159 return NULL;
160 return m_opaque_ptr->m_command.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +0000161}
162
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163void SBPlatformShellCommand::SetCommand(const char *shell_command) {
164 if (shell_command && shell_command[0])
165 m_opaque_ptr->m_command = shell_command;
166 else
167 m_opaque_ptr->m_command.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +0000168}
169
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170const char *SBPlatformShellCommand::GetWorkingDirectory() {
171 if (m_opaque_ptr->m_working_dir.empty())
172 return NULL;
173 return m_opaque_ptr->m_working_dir.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +0000174}
175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
177 if (path && path[0])
178 m_opaque_ptr->m_working_dir = path;
179 else
180 m_opaque_ptr->m_working_dir.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +0000181}
182
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
Pavel Labath19dd1a02018-05-10 10:46:03 +0000184 if (m_opaque_ptr->m_timeout)
185 return m_opaque_ptr->m_timeout->count();
186 return UINT32_MAX;
Greg Claytonfbb76342013-11-20 21:07:01 +0000187}
188
Kate Stoneb9c1b512016-09-06 20:57:50 +0000189void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
Pavel Labath19dd1a02018-05-10 10:46:03 +0000190 if (sec == UINT32_MAX)
191 m_opaque_ptr->m_timeout = llvm::None;
192 else
193 m_opaque_ptr->m_timeout = std::chrono::seconds(sec);
Greg Claytonfbb76342013-11-20 21:07:01 +0000194}
195
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196int SBPlatformShellCommand::GetSignal() { return m_opaque_ptr->m_signo; }
Greg Claytonfbb76342013-11-20 21:07:01 +0000197
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198int SBPlatformShellCommand::GetStatus() { return m_opaque_ptr->m_status; }
Greg Claytonfbb76342013-11-20 21:07:01 +0000199
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200const char *SBPlatformShellCommand::GetOutput() {
201 if (m_opaque_ptr->m_output.empty())
202 return NULL;
203 return m_opaque_ptr->m_output.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +0000204}
205
206//----------------------------------------------------------------------
207// SBPlatform
208//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209SBPlatform::SBPlatform() : m_opaque_sp() {}
210
211SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() {
Zachary Turner97206d52017-05-12 04:51:55 +0000212 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213 if (platform_name && platform_name[0])
214 m_opaque_sp = Platform::Create(ConstString(platform_name), error);
Greg Claytonfbb76342013-11-20 21:07:01 +0000215}
216
Kate Stoneb9c1b512016-09-06 20:57:50 +0000217SBPlatform::~SBPlatform() {}
218
219bool SBPlatform::IsValid() const { return m_opaque_sp.get() != NULL; }
220
221void SBPlatform::Clear() { m_opaque_sp.reset(); }
222
223const char *SBPlatform::GetName() {
224 PlatformSP platform_sp(GetSP());
225 if (platform_sp)
226 return platform_sp->GetName().GetCString();
227 return NULL;
228}
229
230lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
231
232void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
233 m_opaque_sp = platform_sp;
234}
235
236const char *SBPlatform::GetWorkingDirectory() {
237 PlatformSP platform_sp(GetSP());
238 if (platform_sp)
239 return platform_sp->GetWorkingDirectory().GetCString();
240 return NULL;
241}
242
243bool SBPlatform::SetWorkingDirectory(const char *path) {
244 PlatformSP platform_sp(GetSP());
245 if (platform_sp) {
246 if (path)
247 platform_sp->SetWorkingDirectory(FileSpec{path, false});
248 else
249 platform_sp->SetWorkingDirectory(FileSpec{});
250 return true;
251 }
252 return false;
253}
254
255SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
256 SBError sb_error;
257 PlatformSP platform_sp(GetSP());
258 if (platform_sp && connect_options.GetURL()) {
259 Args args;
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000260 args.AppendArgument(
261 llvm::StringRef::withNullAsEmpty(connect_options.GetURL()));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262 sb_error.ref() = platform_sp->ConnectRemote(args);
263 } else {
264 sb_error.SetErrorString("invalid platform");
265 }
266 return sb_error;
267}
268
269void SBPlatform::DisconnectRemote() {
270 PlatformSP platform_sp(GetSP());
271 if (platform_sp)
272 platform_sp->DisconnectRemote();
273}
274
275bool SBPlatform::IsConnected() {
276 PlatformSP platform_sp(GetSP());
277 if (platform_sp)
Jim Inghamca387662018-03-13 21:06:05 +0000278 return platform_sp->IsConnected();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000279 return false;
280}
281
282const char *SBPlatform::GetTriple() {
283 PlatformSP platform_sp(GetSP());
284 if (platform_sp) {
285 ArchSpec arch(platform_sp->GetSystemArchitecture());
286 if (arch.IsValid()) {
287 // Const-ify the string so we don't need to worry about the lifetime of
288 // the string
289 return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
290 }
291 }
292 return NULL;
293}
294
295const char *SBPlatform::GetOSBuild() {
296 PlatformSP platform_sp(GetSP());
297 if (platform_sp) {
298 std::string s;
299 if (platform_sp->GetOSBuildString(s)) {
300 if (!s.empty()) {
301 // Const-ify the string so we don't need to worry about the lifetime of
302 // the string
303 return ConstString(s.c_str()).GetCString();
304 }
305 }
306 }
307 return NULL;
308}
309
310const char *SBPlatform::GetOSDescription() {
311 PlatformSP platform_sp(GetSP());
312 if (platform_sp) {
313 std::string s;
314 if (platform_sp->GetOSKernelDescription(s)) {
315 if (!s.empty()) {
316 // Const-ify the string so we don't need to worry about the lifetime of
317 // the string
318 return ConstString(s.c_str()).GetCString();
319 }
320 }
321 }
322 return NULL;
323}
324
325const char *SBPlatform::GetHostname() {
326 PlatformSP platform_sp(GetSP());
327 if (platform_sp)
328 return platform_sp->GetHostname();
329 return NULL;
330}
331
332uint32_t SBPlatform::GetOSMajorVersion() {
333 uint32_t major, minor, update;
334 PlatformSP platform_sp(GetSP());
335 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
336 return major;
337 return UINT32_MAX;
338}
339
340uint32_t SBPlatform::GetOSMinorVersion() {
341 uint32_t major, minor, update;
342 PlatformSP platform_sp(GetSP());
343 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
344 return minor;
345 return UINT32_MAX;
346}
347
348uint32_t SBPlatform::GetOSUpdateVersion() {
349 uint32_t major, minor, update;
350 PlatformSP platform_sp(GetSP());
351 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
352 return update;
353 return UINT32_MAX;
354}
355
356SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
357 SBError sb_error;
358 PlatformSP platform_sp(GetSP());
359 if (platform_sp) {
360 sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
361 } else {
362 sb_error.SetErrorString("invalid platform");
363 }
364 return sb_error;
365}
366
367SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
368 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
369 if (src.Exists()) {
370 uint32_t permissions = src.ref().GetPermissions();
371 if (permissions == 0) {
Zachary Turner7d86ee52017-03-08 17:56:08 +0000372 if (llvm::sys::fs::is_directory(src.ref().GetPath()))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000373 permissions = eFilePermissionsDirectoryDefault;
374 else
375 permissions = eFilePermissionsFileDefault;
376 }
377
378 return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
379 }
380
Zachary Turner97206d52017-05-12 04:51:55 +0000381 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
383 src.ref().GetPath().c_str());
384 return error;
385 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000386}
387
Kate Stoneb9c1b512016-09-06 20:57:50 +0000388SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
389 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
390 if (src.Exists())
391 return platform_sp->Install(src.ref(), dst.ref());
392
Zachary Turner97206d52017-05-12 04:51:55 +0000393 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000394 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
395 src.ref().GetPath().c_str());
396 return error;
397 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000398}
399
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
401 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
402 const char *command = shell_command.GetCommand();
403 if (!command)
Zachary Turner97206d52017-05-12 04:51:55 +0000404 return Status("invalid shell command (empty)");
Greg Claytonfbb76342013-11-20 21:07:01 +0000405
Kate Stoneb9c1b512016-09-06 20:57:50 +0000406 const char *working_dir = shell_command.GetWorkingDirectory();
407 if (working_dir == NULL) {
408 working_dir = platform_sp->GetWorkingDirectory().GetCString();
409 if (working_dir)
410 shell_command.SetWorkingDirectory(working_dir);
Greg Claytonfbb76342013-11-20 21:07:01 +0000411 }
Pavel Labath19dd1a02018-05-10 10:46:03 +0000412 return platform_sp->RunShellCommand(command, FileSpec{working_dir, false},
413 &shell_command.m_opaque_ptr->m_status,
414 &shell_command.m_opaque_ptr->m_signo,
415 &shell_command.m_opaque_ptr->m_output,
416 shell_command.m_opaque_ptr->m_timeout);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000417 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000418}
419
Kate Stoneb9c1b512016-09-06 20:57:50 +0000420SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
421 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
Pavel Labath62930e52018-01-10 11:57:31 +0000422 ProcessLaunchInfo info = launch_info.ref();
423 Status error = platform_sp->LaunchProcess(info);
424 launch_info.set_ref(info);
425 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426 });
427}
428
429SBError SBPlatform::Kill(const lldb::pid_t pid) {
430 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
431 return platform_sp->KillProcess(pid);
432 });
433}
434
435SBError SBPlatform::ExecuteConnected(
Zachary Turner97206d52017-05-12 04:51:55 +0000436 const std::function<Status(const lldb::PlatformSP &)> &func) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000437 SBError sb_error;
438 const auto platform_sp(GetSP());
439 if (platform_sp) {
440 if (platform_sp->IsConnected())
441 sb_error.ref() = func(platform_sp);
Greg Claytonfbb76342013-11-20 21:07:01 +0000442 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443 sb_error.SetErrorString("not connected");
444 } else
445 sb_error.SetErrorString("invalid platform");
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000446
447 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000448}
449
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
451 SBError sb_error;
452 PlatformSP platform_sp(GetSP());
453 if (platform_sp) {
454 sb_error.ref() =
455 platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions);
456 } else {
457 sb_error.SetErrorString("invalid platform");
458 }
459 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000460}
461
Kate Stoneb9c1b512016-09-06 20:57:50 +0000462uint32_t SBPlatform::GetFilePermissions(const char *path) {
463 PlatformSP platform_sp(GetSP());
464 if (platform_sp) {
465 uint32_t file_permissions = 0;
466 platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions);
467 return file_permissions;
468 }
469 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +0000470}
471
Kate Stoneb9c1b512016-09-06 20:57:50 +0000472SBError SBPlatform::SetFilePermissions(const char *path,
473 uint32_t file_permissions) {
474 SBError sb_error;
475 PlatformSP platform_sp(GetSP());
476 if (platform_sp) {
477 sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false},
478 file_permissions);
479 } else {
480 sb_error.SetErrorString("invalid platform");
481 }
482 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000483}
484
Kate Stoneb9c1b512016-09-06 20:57:50 +0000485SBUnixSignals SBPlatform::GetUnixSignals() const {
486 if (auto platform_sp = GetSP())
487 return SBUnixSignals{platform_sp};
Chaoren Lin98d0a4b2015-07-14 01:09:28 +0000488
Kate Stoneb9c1b512016-09-06 20:57:50 +0000489 return {};
Chaoren Lin98d0a4b2015-07-14 01:09:28 +0000490}