blob: 7ec43f13021f30e3fcda11ce571e2e1e201299a0 [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"
16#include "lldb/Interpreter/Args.h"
Greg Claytonfbb76342013-11-20 21:07:01 +000017#include "lldb/Target/Platform.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000018#include "lldb/Target/Target.h"
Pavel Labath5f19b902017-11-13 16:16:33 +000019#include "lldb/Utility/ArchSpec.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)
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;
60 }
61
62 ~PlatformShellCommand() {}
63
64 std::string m_command;
65 std::string m_working_dir;
66 std::string m_output;
67 int m_status;
68 int m_signo;
69 uint32_t m_timeout_sec;
Greg Claytonfbb76342013-11-20 21:07:01 +000070};
71//----------------------------------------------------------------------
72// SBPlatformConnectOptions
73//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000074SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
75 : m_opaque_ptr(new PlatformConnectOptions(url)) {}
76
77SBPlatformConnectOptions::SBPlatformConnectOptions(
78 const SBPlatformConnectOptions &rhs)
79 : m_opaque_ptr(new PlatformConnectOptions()) {
80 *m_opaque_ptr = *rhs.m_opaque_ptr;
Greg Claytonfbb76342013-11-20 21:07:01 +000081}
82
Kate Stoneb9c1b512016-09-06 20:57:50 +000083SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
84
85void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
86 *m_opaque_ptr = *rhs.m_opaque_ptr;
Greg Claytonfbb76342013-11-20 21:07:01 +000087}
88
Kate Stoneb9c1b512016-09-06 20:57:50 +000089const char *SBPlatformConnectOptions::GetURL() {
90 if (m_opaque_ptr->m_url.empty())
91 return NULL;
92 return m_opaque_ptr->m_url.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +000093}
94
Kate Stoneb9c1b512016-09-06 20:57:50 +000095void SBPlatformConnectOptions::SetURL(const char *url) {
96 if (url && url[0])
97 m_opaque_ptr->m_url = url;
98 else
99 m_opaque_ptr->m_url.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +0000100}
101
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102bool SBPlatformConnectOptions::GetRsyncEnabled() {
103 return m_opaque_ptr->m_rsync_enabled;
Greg Claytonfbb76342013-11-20 21:07:01 +0000104}
105
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106void 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;
114 else
115 m_opaque_ptr->m_rsync_remote_path_prefix.clear();
116
117 if (options && options[0])
118 m_opaque_ptr->m_rsync_options = options;
119 else
120 m_opaque_ptr->m_rsync_options.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +0000121}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122
123void SBPlatformConnectOptions::DisableRsync() {
124 m_opaque_ptr->m_rsync_enabled = false;
Greg Claytonfbb76342013-11-20 21:07:01 +0000125}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000126
127const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
128 return m_opaque_ptr->m_local_cache_directory.GetCString();
129}
130
131void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
132 if (path && path[0])
133 m_opaque_ptr->m_local_cache_directory.SetCString(path);
134 else
135 m_opaque_ptr->m_local_cache_directory = ConstString();
Greg Claytonfbb76342013-11-20 21:07:01 +0000136}
137
138//----------------------------------------------------------------------
139// SBPlatformShellCommand
140//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
142 : m_opaque_ptr(new PlatformShellCommand(shell_command)) {}
143
144SBPlatformShellCommand::SBPlatformShellCommand(
145 const SBPlatformShellCommand &rhs)
146 : m_opaque_ptr(new PlatformShellCommand()) {
147 *m_opaque_ptr = *rhs.m_opaque_ptr;
Greg Claytonfbb76342013-11-20 21:07:01 +0000148}
149
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
151
152void SBPlatformShellCommand::Clear() {
153 m_opaque_ptr->m_output = std::string();
154 m_opaque_ptr->m_status = 0;
155 m_opaque_ptr->m_signo = 0;
Greg Claytonfbb76342013-11-20 21:07:01 +0000156}
157
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158const char *SBPlatformShellCommand::GetCommand() {
159 if (m_opaque_ptr->m_command.empty())
160 return NULL;
161 return m_opaque_ptr->m_command.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +0000162}
163
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164void SBPlatformShellCommand::SetCommand(const char *shell_command) {
165 if (shell_command && shell_command[0])
166 m_opaque_ptr->m_command = shell_command;
167 else
168 m_opaque_ptr->m_command.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +0000169}
170
Kate Stoneb9c1b512016-09-06 20:57:50 +0000171const char *SBPlatformShellCommand::GetWorkingDirectory() {
172 if (m_opaque_ptr->m_working_dir.empty())
173 return NULL;
174 return m_opaque_ptr->m_working_dir.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +0000175}
176
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
178 if (path && path[0])
179 m_opaque_ptr->m_working_dir = path;
180 else
181 m_opaque_ptr->m_working_dir.clear();
Greg Claytonfbb76342013-11-20 21:07:01 +0000182}
183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
185 return m_opaque_ptr->m_timeout_sec;
Greg Claytonfbb76342013-11-20 21:07:01 +0000186}
187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
189 m_opaque_ptr->m_timeout_sec = sec;
Greg Claytonfbb76342013-11-20 21:07:01 +0000190}
191
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192int SBPlatformShellCommand::GetSignal() { return m_opaque_ptr->m_signo; }
Greg Claytonfbb76342013-11-20 21:07:01 +0000193
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194int SBPlatformShellCommand::GetStatus() { return m_opaque_ptr->m_status; }
Greg Claytonfbb76342013-11-20 21:07:01 +0000195
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196const char *SBPlatformShellCommand::GetOutput() {
197 if (m_opaque_ptr->m_output.empty())
198 return NULL;
199 return m_opaque_ptr->m_output.c_str();
Greg Claytonfbb76342013-11-20 21:07:01 +0000200}
201
202//----------------------------------------------------------------------
203// SBPlatform
204//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205SBPlatform::SBPlatform() : m_opaque_sp() {}
206
207SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() {
Zachary Turner97206d52017-05-12 04:51:55 +0000208 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209 if (platform_name && platform_name[0])
210 m_opaque_sp = Platform::Create(ConstString(platform_name), error);
Greg Claytonfbb76342013-11-20 21:07:01 +0000211}
212
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213SBPlatform::~SBPlatform() {}
214
215bool SBPlatform::IsValid() const { return m_opaque_sp.get() != NULL; }
216
217void SBPlatform::Clear() { m_opaque_sp.reset(); }
218
219const char *SBPlatform::GetName() {
220 PlatformSP platform_sp(GetSP());
221 if (platform_sp)
222 return platform_sp->GetName().GetCString();
223 return NULL;
224}
225
226lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
227
228void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
229 m_opaque_sp = platform_sp;
230}
231
232const char *SBPlatform::GetWorkingDirectory() {
233 PlatformSP platform_sp(GetSP());
234 if (platform_sp)
235 return platform_sp->GetWorkingDirectory().GetCString();
236 return NULL;
237}
238
239bool SBPlatform::SetWorkingDirectory(const char *path) {
240 PlatformSP platform_sp(GetSP());
241 if (platform_sp) {
242 if (path)
243 platform_sp->SetWorkingDirectory(FileSpec{path, false});
244 else
245 platform_sp->SetWorkingDirectory(FileSpec{});
246 return true;
247 }
248 return false;
249}
250
251SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
252 SBError sb_error;
253 PlatformSP platform_sp(GetSP());
254 if (platform_sp && connect_options.GetURL()) {
255 Args args;
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000256 args.AppendArgument(
257 llvm::StringRef::withNullAsEmpty(connect_options.GetURL()));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 sb_error.ref() = platform_sp->ConnectRemote(args);
259 } else {
260 sb_error.SetErrorString("invalid platform");
261 }
262 return sb_error;
263}
264
265void SBPlatform::DisconnectRemote() {
266 PlatformSP platform_sp(GetSP());
267 if (platform_sp)
268 platform_sp->DisconnectRemote();
269}
270
271bool SBPlatform::IsConnected() {
272 PlatformSP platform_sp(GetSP());
273 if (platform_sp)
274 platform_sp->IsConnected();
275 return false;
276}
277
278const char *SBPlatform::GetTriple() {
279 PlatformSP platform_sp(GetSP());
280 if (platform_sp) {
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
284 // the string
285 return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
286 }
287 }
288 return NULL;
289}
290
291const char *SBPlatform::GetOSBuild() {
292 PlatformSP platform_sp(GetSP());
293 if (platform_sp) {
294 std::string s;
295 if (platform_sp->GetOSBuildString(s)) {
296 if (!s.empty()) {
297 // Const-ify the string so we don't need to worry about the lifetime of
298 // the string
299 return ConstString(s.c_str()).GetCString();
300 }
301 }
302 }
303 return NULL;
304}
305
306const char *SBPlatform::GetOSDescription() {
307 PlatformSP platform_sp(GetSP());
308 if (platform_sp) {
309 std::string s;
310 if (platform_sp->GetOSKernelDescription(s)) {
311 if (!s.empty()) {
312 // Const-ify the string so we don't need to worry about the lifetime of
313 // the string
314 return ConstString(s.c_str()).GetCString();
315 }
316 }
317 }
318 return NULL;
319}
320
321const char *SBPlatform::GetHostname() {
322 PlatformSP platform_sp(GetSP());
323 if (platform_sp)
324 return platform_sp->GetHostname();
325 return NULL;
326}
327
328uint32_t SBPlatform::GetOSMajorVersion() {
329 uint32_t major, minor, update;
330 PlatformSP platform_sp(GetSP());
331 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
332 return major;
333 return UINT32_MAX;
334}
335
336uint32_t SBPlatform::GetOSMinorVersion() {
337 uint32_t major, minor, update;
338 PlatformSP platform_sp(GetSP());
339 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
340 return minor;
341 return UINT32_MAX;
342}
343
344uint32_t SBPlatform::GetOSUpdateVersion() {
345 uint32_t major, minor, update;
346 PlatformSP platform_sp(GetSP());
347 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
348 return update;
349 return UINT32_MAX;
350}
351
352SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
353 SBError sb_error;
354 PlatformSP platform_sp(GetSP());
355 if (platform_sp) {
356 sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
357 } else {
358 sb_error.SetErrorString("invalid platform");
359 }
360 return sb_error;
361}
362
363SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
364 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
365 if (src.Exists()) {
366 uint32_t permissions = src.ref().GetPermissions();
367 if (permissions == 0) {
Zachary Turner7d86ee52017-03-08 17:56:08 +0000368 if (llvm::sys::fs::is_directory(src.ref().GetPath()))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369 permissions = eFilePermissionsDirectoryDefault;
370 else
371 permissions = eFilePermissionsFileDefault;
372 }
373
374 return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
375 }
376
Zachary Turner97206d52017-05-12 04:51:55 +0000377 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000378 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
379 src.ref().GetPath().c_str());
380 return error;
381 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000382}
383
Kate Stoneb9c1b512016-09-06 20:57:50 +0000384SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
385 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
386 if (src.Exists())
387 return platform_sp->Install(src.ref(), dst.ref());
388
Zachary Turner97206d52017-05-12 04:51:55 +0000389 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
391 src.ref().GetPath().c_str());
392 return error;
393 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000394}
395
Kate Stoneb9c1b512016-09-06 20:57:50 +0000396SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
397 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
398 const char *command = shell_command.GetCommand();
399 if (!command)
Zachary Turner97206d52017-05-12 04:51:55 +0000400 return Status("invalid shell command (empty)");
Greg Claytonfbb76342013-11-20 21:07:01 +0000401
Kate Stoneb9c1b512016-09-06 20:57:50 +0000402 const char *working_dir = shell_command.GetWorkingDirectory();
403 if (working_dir == NULL) {
404 working_dir = platform_sp->GetWorkingDirectory().GetCString();
405 if (working_dir)
406 shell_command.SetWorkingDirectory(working_dir);
Greg Claytonfbb76342013-11-20 21:07:01 +0000407 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408 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);
414 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000415}
416
Kate Stoneb9c1b512016-09-06 20:57:50 +0000417SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
418 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
419 return platform_sp->LaunchProcess(launch_info.ref());
420 });
421}
422
423SBError SBPlatform::Kill(const lldb::pid_t pid) {
424 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
425 return platform_sp->KillProcess(pid);
426 });
427}
428
429SBError SBPlatform::ExecuteConnected(
Zachary Turner97206d52017-05-12 04:51:55 +0000430 const std::function<Status(const lldb::PlatformSP &)> &func) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000431 SBError sb_error;
432 const auto platform_sp(GetSP());
433 if (platform_sp) {
434 if (platform_sp->IsConnected())
435 sb_error.ref() = func(platform_sp);
Greg Claytonfbb76342013-11-20 21:07:01 +0000436 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000437 sb_error.SetErrorString("not connected");
438 } else
439 sb_error.SetErrorString("invalid platform");
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000440
441 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000442}
443
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
445 SBError sb_error;
446 PlatformSP platform_sp(GetSP());
447 if (platform_sp) {
448 sb_error.ref() =
449 platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions);
450 } else {
451 sb_error.SetErrorString("invalid platform");
452 }
453 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000454}
455
Kate Stoneb9c1b512016-09-06 20:57:50 +0000456uint32_t SBPlatform::GetFilePermissions(const char *path) {
457 PlatformSP platform_sp(GetSP());
458 if (platform_sp) {
459 uint32_t file_permissions = 0;
460 platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions);
461 return file_permissions;
462 }
463 return 0;
Greg Claytonfbb76342013-11-20 21:07:01 +0000464}
465
Kate Stoneb9c1b512016-09-06 20:57:50 +0000466SBError SBPlatform::SetFilePermissions(const char *path,
467 uint32_t file_permissions) {
468 SBError sb_error;
469 PlatformSP platform_sp(GetSP());
470 if (platform_sp) {
471 sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false},
472 file_permissions);
473 } else {
474 sb_error.SetErrorString("invalid platform");
475 }
476 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000477}
478
Kate Stoneb9c1b512016-09-06 20:57:50 +0000479SBUnixSignals SBPlatform::GetUnixSignals() const {
480 if (auto platform_sp = GetSP())
481 return SBUnixSignals{platform_sp};
Chaoren Lin98d0a4b2015-07-14 01:09:28 +0000482
Kate Stoneb9c1b512016-09-06 20:57:50 +0000483 return {};
Chaoren Lin98d0a4b2015-07-14 01:09:28 +0000484}