blob: aedad871cd2088792d2196794a434f601203c3e0 [file] [log] [blame]
Greg Claytonfbb76342013-11-20 21:07:011//===-- 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:1513#include "lldb/API/SBLaunchInfo.h"
Chaoren Lin98d0a4b2015-07-14 01:09:2814#include "lldb/API/SBUnixSignals.h"
Greg Claytonfbb76342013-11-20 21:07:0115#include "lldb/Host/File.h"
Greg Claytonfbb76342013-11-20 21:07:0116#include "lldb/Target/Platform.h"
Kate Stoneb9c1b512016-09-06 20:57:5017#include "lldb/Target/Target.h"
Pavel Labath5f19b902017-11-13 16:16:3318#include "lldb/Utility/ArchSpec.h"
Pavel Labath145d95c2018-04-17 18:53:3519#include "lldb/Utility/Args.h"
Zachary Turner97206d52017-05-12 04:51:5520#include "lldb/Utility/Status.h"
Greg Claytonfbb76342013-11-20 21:07:0121
Zachary Turner7d86ee52017-03-08 17:56:0822#include "llvm/Support/FileSystem.h"
23
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:1524#include <functional>
25
Greg Claytonfbb76342013-11-20 21:07:0126using namespace lldb;
27using namespace lldb_private;
28
29//----------------------------------------------------------------------
30// PlatformConnectOptions
31//----------------------------------------------------------------------
32struct PlatformConnectOptions {
Kate Stoneb9c1b512016-09-06 20:57:5033 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:0140
Kate Stoneb9c1b512016-09-06 20:57:5041 ~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:0149};
50
51//----------------------------------------------------------------------
52// PlatformShellCommand
53//----------------------------------------------------------------------
54struct PlatformShellCommand {
Kate Stoneb9c1b512016-09-06 20:57:5055 PlatformShellCommand(const char *shell_command = NULL)
Pavel Labath19dd1a02018-05-10 10:46:0356 : m_command(), m_working_dir(), m_status(0), m_signo(0) {
Kate Stoneb9c1b512016-09-06 20:57:5057 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:0368 Timeout<std::ratio<1>> m_timeout = llvm::None;
Greg Claytonfbb76342013-11-20 21:07:0169};
70//----------------------------------------------------------------------
71// SBPlatformConnectOptions
72//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:5073SBPlatformConnectOptions::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:0180}
81
Kate Stoneb9c1b512016-09-06 20:57:5082SBPlatformConnectOptions::~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:0186}
87
Kate Stoneb9c1b512016-09-06 20:57:5088const 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:0192}
93
Kate Stoneb9c1b512016-09-06 20:57:5094void 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:0199}
100
Kate Stoneb9c1b512016-09-06 20:57:50101bool SBPlatformConnectOptions::GetRsyncEnabled() {
102 return m_opaque_ptr->m_rsync_enabled;
Greg Claytonfbb76342013-11-20 21:07:01103}
104
Kate Stoneb9c1b512016-09-06 20:57:50105void 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:01120}
Kate Stoneb9c1b512016-09-06 20:57:50121
122void SBPlatformConnectOptions::DisableRsync() {
123 m_opaque_ptr->m_rsync_enabled = false;
Greg Claytonfbb76342013-11-20 21:07:01124}
Kate Stoneb9c1b512016-09-06 20:57:50125
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:01135}
136
137//----------------------------------------------------------------------
138// SBPlatformShellCommand
139//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50140SBPlatformShellCommand::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:01147}
148
Kate Stoneb9c1b512016-09-06 20:57:50149SBPlatformShellCommand::~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:01155}
156
Kate Stoneb9c1b512016-09-06 20:57:50157const 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:01161}
162
Kate Stoneb9c1b512016-09-06 20:57:50163void 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:01168}
169
Kate Stoneb9c1b512016-09-06 20:57:50170const 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:01174}
175
Kate Stoneb9c1b512016-09-06 20:57:50176void 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:01181}
182
Kate Stoneb9c1b512016-09-06 20:57:50183uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
Pavel Labath19dd1a02018-05-10 10:46:03184 if (m_opaque_ptr->m_timeout)
185 return m_opaque_ptr->m_timeout->count();
186 return UINT32_MAX;
Greg Claytonfbb76342013-11-20 21:07:01187}
188
Kate Stoneb9c1b512016-09-06 20:57:50189void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
Pavel Labath19dd1a02018-05-10 10:46:03190 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:01194}
195
Kate Stoneb9c1b512016-09-06 20:57:50196int SBPlatformShellCommand::GetSignal() { return m_opaque_ptr->m_signo; }
Greg Claytonfbb76342013-11-20 21:07:01197
Kate Stoneb9c1b512016-09-06 20:57:50198int SBPlatformShellCommand::GetStatus() { return m_opaque_ptr->m_status; }
Greg Claytonfbb76342013-11-20 21:07:01199
Kate Stoneb9c1b512016-09-06 20:57:50200const 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:01204}
205
206//----------------------------------------------------------------------
207// SBPlatform
208//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50209SBPlatform::SBPlatform() : m_opaque_sp() {}
210
211SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() {
Zachary Turner97206d52017-05-12 04:51:55212 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50213 if (platform_name && platform_name[0])
214 m_opaque_sp = Platform::Create(ConstString(platform_name), error);
Greg Claytonfbb76342013-11-20 21:07:01215}
216
Kate Stoneb9c1b512016-09-06 20:57:50217SBPlatform::~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)
Jonas Devlieghere8f3be7a2018-11-01 21:05:36247 platform_sp->SetWorkingDirectory(FileSpec(path));
Kate Stoneb9c1b512016-09-06 20:57:50248 else
Jonas Devlieghere8f3be7a2018-11-01 21:05:36249 platform_sp->SetWorkingDirectory(FileSpec());
Kate Stoneb9c1b512016-09-06 20:57:50250 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:06260 args.AppendArgument(
261 llvm::StringRef::withNullAsEmpty(connect_options.GetURL()));
Kate Stoneb9c1b512016-09-06 20:57:50262 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:05278 return platform_sp->IsConnected();
Kate Stoneb9c1b512016-09-06 20:57:50279 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() {
Pavel Labath2272c482018-06-18 15:02:23333 llvm::VersionTuple version;
334 if (PlatformSP platform_sp = GetSP())
335 version = platform_sp->GetOSVersion();
336 return version.empty() ? UINT32_MAX : version.getMajor();
Kate Stoneb9c1b512016-09-06 20:57:50337}
338
339uint32_t SBPlatform::GetOSMinorVersion() {
Pavel Labath2272c482018-06-18 15:02:23340 llvm::VersionTuple version;
341 if (PlatformSP platform_sp = GetSP())
342 version = platform_sp->GetOSVersion();
343 return version.getMinor().getValueOr(UINT32_MAX);
Kate Stoneb9c1b512016-09-06 20:57:50344}
345
346uint32_t SBPlatform::GetOSUpdateVersion() {
Pavel Labath2272c482018-06-18 15:02:23347 llvm::VersionTuple version;
348 if (PlatformSP platform_sp = GetSP())
349 version = platform_sp->GetOSVersion();
350 return version.getSubminor().getValueOr(UINT32_MAX);
Kate Stoneb9c1b512016-09-06 20:57:50351}
352
353SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
354 SBError sb_error;
355 PlatformSP platform_sp(GetSP());
356 if (platform_sp) {
357 sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
358 } else {
359 sb_error.SetErrorString("invalid platform");
360 }
361 return sb_error;
362}
363
364SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
365 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
366 if (src.Exists()) {
Jonas Devlieghere7c5310b2018-11-01 15:47:33367 uint32_t permissions = FileSystem::Instance().GetPermissions(src.ref());
Kate Stoneb9c1b512016-09-06 20:57:50368 if (permissions == 0) {
Jonas Devlieghere3a58d892018-11-08 00:14:50369 if (FileSystem::Instance().IsDirectory(src.ref()))
Kate Stoneb9c1b512016-09-06 20:57:50370 permissions = eFilePermissionsDirectoryDefault;
371 else
372 permissions = eFilePermissionsFileDefault;
373 }
374
375 return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
376 }
377
Zachary Turner97206d52017-05-12 04:51:55378 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50379 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
380 src.ref().GetPath().c_str());
381 return error;
382 });
Greg Claytonfbb76342013-11-20 21:07:01383}
384
Kate Stoneb9c1b512016-09-06 20:57:50385SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
386 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
387 if (src.Exists())
388 return platform_sp->Install(src.ref(), dst.ref());
389
Zachary Turner97206d52017-05-12 04:51:55390 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50391 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
392 src.ref().GetPath().c_str());
393 return error;
394 });
Greg Claytonfbb76342013-11-20 21:07:01395}
396
Kate Stoneb9c1b512016-09-06 20:57:50397SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
398 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
399 const char *command = shell_command.GetCommand();
400 if (!command)
Zachary Turner97206d52017-05-12 04:51:55401 return Status("invalid shell command (empty)");
Greg Claytonfbb76342013-11-20 21:07:01402
Kate Stoneb9c1b512016-09-06 20:57:50403 const char *working_dir = shell_command.GetWorkingDirectory();
404 if (working_dir == NULL) {
405 working_dir = platform_sp->GetWorkingDirectory().GetCString();
406 if (working_dir)
407 shell_command.SetWorkingDirectory(working_dir);
Greg Claytonfbb76342013-11-20 21:07:01408 }
Jonas Devlieghere8f3be7a2018-11-01 21:05:36409 return platform_sp->RunShellCommand(command, FileSpec(working_dir),
Pavel Labath19dd1a02018-05-10 10:46:03410 &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);
Kate Stoneb9c1b512016-09-06 20:57:50414 });
Greg Claytonfbb76342013-11-20 21:07:01415}
416
Kate Stoneb9c1b512016-09-06 20:57:50417SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
418 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
Pavel Labath62930e52018-01-10 11:57:31419 ProcessLaunchInfo info = launch_info.ref();
420 Status error = platform_sp->LaunchProcess(info);
421 launch_info.set_ref(info);
422 return error;
Kate Stoneb9c1b512016-09-06 20:57:50423 });
424}
425
426SBError SBPlatform::Kill(const lldb::pid_t pid) {
427 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
428 return platform_sp->KillProcess(pid);
429 });
430}
431
432SBError SBPlatform::ExecuteConnected(
Zachary Turner97206d52017-05-12 04:51:55433 const std::function<Status(const lldb::PlatformSP &)> &func) {
Kate Stoneb9c1b512016-09-06 20:57:50434 SBError sb_error;
435 const auto platform_sp(GetSP());
436 if (platform_sp) {
437 if (platform_sp->IsConnected())
438 sb_error.ref() = func(platform_sp);
Greg Claytonfbb76342013-11-20 21:07:01439 else
Kate Stoneb9c1b512016-09-06 20:57:50440 sb_error.SetErrorString("not connected");
441 } else
442 sb_error.SetErrorString("invalid platform");
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15443
444 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01445}
446
Kate Stoneb9c1b512016-09-06 20:57:50447SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
448 SBError sb_error;
449 PlatformSP platform_sp(GetSP());
450 if (platform_sp) {
451 sb_error.ref() =
Jonas Devlieghere8f3be7a2018-11-01 21:05:36452 platform_sp->MakeDirectory(FileSpec(path), file_permissions);
Kate Stoneb9c1b512016-09-06 20:57:50453 } else {
454 sb_error.SetErrorString("invalid platform");
455 }
456 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01457}
458
Kate Stoneb9c1b512016-09-06 20:57:50459uint32_t SBPlatform::GetFilePermissions(const char *path) {
460 PlatformSP platform_sp(GetSP());
461 if (platform_sp) {
462 uint32_t file_permissions = 0;
Jonas Devlieghere8f3be7a2018-11-01 21:05:36463 platform_sp->GetFilePermissions(FileSpec(path), file_permissions);
Kate Stoneb9c1b512016-09-06 20:57:50464 return file_permissions;
465 }
466 return 0;
Greg Claytonfbb76342013-11-20 21:07:01467}
468
Kate Stoneb9c1b512016-09-06 20:57:50469SBError SBPlatform::SetFilePermissions(const char *path,
470 uint32_t file_permissions) {
471 SBError sb_error;
472 PlatformSP platform_sp(GetSP());
473 if (platform_sp) {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36474 sb_error.ref() =
475 platform_sp->SetFilePermissions(FileSpec(path), file_permissions);
Kate Stoneb9c1b512016-09-06 20:57:50476 } else {
477 sb_error.SetErrorString("invalid platform");
478 }
479 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01480}
481
Kate Stoneb9c1b512016-09-06 20:57:50482SBUnixSignals SBPlatform::GetUnixSignals() const {
483 if (auto platform_sp = GetSP())
484 return SBUnixSignals{platform_sp};
Chaoren Lin98d0a4b2015-07-14 01:09:28485
Kate Stoneb9c1b512016-09-06 20:57:50486 return {};
Chaoren Lin98d0a4b2015-07-14 01:09:28487}