blob: 5662f36b514d029464d3ab83a2fbe2bd2d267398 [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"
Greg Claytonfbb76342013-11-20 21:07:01 +000014#include "lldb/Core/ArchSpec.h"
15#include "lldb/Core/Error.h"
16#include "lldb/Host/File.h"
17#include "lldb/Interpreter/Args.h"
18#include "lldb/Target/Target.h"
19#include "lldb/Target/Platform.h"
20
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +000021#include <functional>
22
Greg Claytonfbb76342013-11-20 21:07:01 +000023using namespace lldb;
24using namespace lldb_private;
25
26//----------------------------------------------------------------------
27// PlatformConnectOptions
28//----------------------------------------------------------------------
29struct PlatformConnectOptions {
30 PlatformConnectOptions(const char *url = NULL) :
31 m_url(),
32 m_rsync_options(),
33 m_rsync_remote_path_prefix(),
34 m_rsync_enabled(false),
35 m_rsync_omit_hostname_from_remote_path(false),
36 m_local_cache_directory ()
37 {
38 if (url && url[0])
39 m_url = url;
40 }
41
42 ~PlatformConnectOptions()
43 {
44 }
45
46 std::string m_url;
47 std::string m_rsync_options;
48 std::string m_rsync_remote_path_prefix;
49 bool m_rsync_enabled;
50 bool m_rsync_omit_hostname_from_remote_path;
51 ConstString m_local_cache_directory;
52};
53
54//----------------------------------------------------------------------
55// PlatformShellCommand
56//----------------------------------------------------------------------
57struct PlatformShellCommand {
58 PlatformShellCommand(const char *shell_command = NULL) :
59 m_command(),
60 m_working_dir(),
61 m_status(0),
62 m_signo(0),
63 m_timeout_sec(UINT32_MAX)
64 {
65 if (shell_command && shell_command[0])
66 m_command = shell_command;
67 }
68
69 ~PlatformShellCommand()
70 {
71 }
72
73 std::string m_command;
74 std::string m_working_dir;
75 std::string m_output;
76 int m_status;
77 int m_signo;
78 uint32_t m_timeout_sec;
79};
80//----------------------------------------------------------------------
81// SBPlatformConnectOptions
82//----------------------------------------------------------------------
83SBPlatformConnectOptions::SBPlatformConnectOptions (const char *url) :
84 m_opaque_ptr(new PlatformConnectOptions(url))
85{
86
87}
88
89SBPlatformConnectOptions::SBPlatformConnectOptions(const SBPlatformConnectOptions &rhs) :
90 m_opaque_ptr(new PlatformConnectOptions())
91{
92 *m_opaque_ptr = *rhs.m_opaque_ptr;
93}
94
95SBPlatformConnectOptions::~SBPlatformConnectOptions ()
96{
97 delete m_opaque_ptr;
98}
99
100void
101SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs)
102{
103 *m_opaque_ptr = *rhs.m_opaque_ptr;
104}
105
106const char *
107SBPlatformConnectOptions::GetURL()
108{
109 if (m_opaque_ptr->m_url.empty())
110 return NULL;
111 return m_opaque_ptr->m_url.c_str();
112}
113
114void
115SBPlatformConnectOptions::SetURL(const char *url)
116{
117 if (url && url[0])
118 m_opaque_ptr->m_url = url;
119 else
120 m_opaque_ptr->m_url.clear();
121}
122
123bool
124SBPlatformConnectOptions::GetRsyncEnabled()
125{
126 return m_opaque_ptr->m_rsync_enabled;
127}
128
129void
130SBPlatformConnectOptions::EnableRsync (const char *options,
131 const char *remote_path_prefix,
132 bool omit_hostname_from_remote_path)
133{
134 m_opaque_ptr->m_rsync_enabled = true;
135 m_opaque_ptr->m_rsync_omit_hostname_from_remote_path = omit_hostname_from_remote_path;
136 if (remote_path_prefix && remote_path_prefix[0])
137 m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
138 else
139 m_opaque_ptr->m_rsync_remote_path_prefix.clear();
140
141 if (options && options[0])
142 m_opaque_ptr->m_rsync_options = options;
143 else
144 m_opaque_ptr->m_rsync_options.clear();
145
146}
147
148void
149SBPlatformConnectOptions::DisableRsync ()
150{
151 m_opaque_ptr->m_rsync_enabled = false;
152}
153
154const char *
155SBPlatformConnectOptions::GetLocalCacheDirectory()
156{
157 return m_opaque_ptr->m_local_cache_directory.GetCString();
158}
159
160void
161SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path)
162{
163 if (path && path[0])
164 m_opaque_ptr->m_local_cache_directory.SetCString(path);
165 else
166 m_opaque_ptr->m_local_cache_directory = ConstString();
167}
168
169//----------------------------------------------------------------------
170// SBPlatformShellCommand
171//----------------------------------------------------------------------
172SBPlatformShellCommand::SBPlatformShellCommand (const char *shell_command) :
173 m_opaque_ptr(new PlatformShellCommand(shell_command))
174{
175}
176
177SBPlatformShellCommand::SBPlatformShellCommand (const SBPlatformShellCommand &rhs) :
178 m_opaque_ptr(new PlatformShellCommand())
179{
180 *m_opaque_ptr = *rhs.m_opaque_ptr;
181}
182
183SBPlatformShellCommand::~SBPlatformShellCommand()
184{
185 delete m_opaque_ptr;
186}
187
188void
189SBPlatformShellCommand::Clear()
190{
191 m_opaque_ptr->m_output = std::move(std::string());
192 m_opaque_ptr->m_status = 0;
193 m_opaque_ptr->m_signo = 0;
194}
195
196const char *
197SBPlatformShellCommand::GetCommand()
198{
199 if (m_opaque_ptr->m_command.empty())
200 return NULL;
201 return m_opaque_ptr->m_command.c_str();
202}
203
204void
205SBPlatformShellCommand::SetCommand(const char *shell_command)
206{
207 if (shell_command && shell_command[0])
208 m_opaque_ptr->m_command = shell_command;
209 else
210 m_opaque_ptr->m_command.clear();
211}
212
213const char *
214SBPlatformShellCommand::GetWorkingDirectory ()
215{
216 if (m_opaque_ptr->m_working_dir.empty())
217 return NULL;
218 return m_opaque_ptr->m_working_dir.c_str();
219}
220
221void
222SBPlatformShellCommand::SetWorkingDirectory (const char *path)
223{
224 if (path && path[0])
225 m_opaque_ptr->m_working_dir = path;
226 else
227 m_opaque_ptr->m_working_dir.clear();
228}
229
230uint32_t
231SBPlatformShellCommand::GetTimeoutSeconds ()
232{
233 return m_opaque_ptr->m_timeout_sec;
234}
235
236void
237SBPlatformShellCommand::SetTimeoutSeconds (uint32_t sec)
238{
239 m_opaque_ptr->m_timeout_sec = sec;
240}
241
242int
243SBPlatformShellCommand::GetSignal ()
244{
245 return m_opaque_ptr->m_signo;
246}
247
248int
249SBPlatformShellCommand::GetStatus ()
250{
251 return m_opaque_ptr->m_status;
252}
253
254const char *
255SBPlatformShellCommand::GetOutput ()
256{
257 if (m_opaque_ptr->m_output.empty())
258 return NULL;
259 return m_opaque_ptr->m_output.c_str();
260}
261
262//----------------------------------------------------------------------
263// SBPlatform
264//----------------------------------------------------------------------
265SBPlatform::SBPlatform () :
266 m_opaque_sp ()
267{
268
269}
270
271SBPlatform::SBPlatform (const char *platform_name) :
272 m_opaque_sp ()
273{
274 Error error;
Greg Clayton615eb7e2014-09-19 20:11:50 +0000275 if (platform_name && platform_name[0])
276 m_opaque_sp = Platform::Create (ConstString(platform_name), error);
Greg Claytonfbb76342013-11-20 21:07:01 +0000277}
278
279SBPlatform::~SBPlatform()
280{
281}
282
283bool
284SBPlatform::IsValid () const
285{
286 return m_opaque_sp.get() != NULL;
287}
288
289void
290SBPlatform::Clear ()
291{
292 m_opaque_sp.reset();
293}
294
295const char *
296SBPlatform::GetName ()
297{
298 PlatformSP platform_sp(GetSP());
299 if (platform_sp)
300 return platform_sp->GetName().GetCString();
301 return NULL;
302}
303
304lldb::PlatformSP
305SBPlatform::GetSP () const
306{
307 return m_opaque_sp;
308}
309
310void
311SBPlatform::SetSP (const lldb::PlatformSP& platform_sp)
312{
313 m_opaque_sp = platform_sp;
314}
315
316const char *
317SBPlatform::GetWorkingDirectory()
318{
319 PlatformSP platform_sp(GetSP());
320 if (platform_sp)
321 return platform_sp->GetWorkingDirectory().GetCString();
322 return NULL;
323}
324
325bool
326SBPlatform::SetWorkingDirectory(const char *path)
327{
328 PlatformSP platform_sp(GetSP());
329 if (platform_sp)
330 {
331 if (path)
Chaoren Lind3173f32015-05-29 19:52:29 +0000332 platform_sp->SetWorkingDirectory(FileSpec{path, false});
Greg Claytonfbb76342013-11-20 21:07:01 +0000333 else
Chaoren Lind3173f32015-05-29 19:52:29 +0000334 platform_sp->SetWorkingDirectory(FileSpec{});
Greg Claytonfbb76342013-11-20 21:07:01 +0000335 return true;
336 }
337 return false;
338}
339
340SBError
341SBPlatform::ConnectRemote (SBPlatformConnectOptions &connect_options)
342{
343 SBError sb_error;
344 PlatformSP platform_sp(GetSP());
345 if (platform_sp && connect_options.GetURL())
346 {
347 Args args;
348 args.AppendArgument(connect_options.GetURL());
349 sb_error.ref() = platform_sp->ConnectRemote(args);
350 }
351 else
352 {
353 sb_error.SetErrorString("invalid platform");
354 }
355 return sb_error;
356}
357
358void
359SBPlatform::DisconnectRemote ()
360{
361 PlatformSP platform_sp(GetSP());
362 if (platform_sp)
363 platform_sp->DisconnectRemote();
364}
365
366bool
367SBPlatform::IsConnected()
368{
369 PlatformSP platform_sp(GetSP());
370 if (platform_sp)
371 platform_sp->IsConnected();
372 return false;
373}
374
375const char *
376SBPlatform::GetTriple()
377{
378 PlatformSP platform_sp(GetSP());
379 if (platform_sp)
380 {
Tamas Berghammerccd28a12015-03-04 11:18:34 +0000381 ArchSpec arch(platform_sp->GetSystemArchitecture());
Greg Claytonfbb76342013-11-20 21:07:01 +0000382 if (arch.IsValid())
383 {
384 // Const-ify the string so we don't need to worry about the lifetime of the string
385 return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
386 }
387 }
388 return NULL;
389}
390
391const char *
392SBPlatform::GetOSBuild()
393{
394 PlatformSP platform_sp(GetSP());
395 if (platform_sp)
396 {
397 std::string s;
398 if (platform_sp->GetOSBuildString(s))
399 {
400 if (!s.empty())
401 {
402 // Const-ify the string so we don't need to worry about the lifetime of the string
403 return ConstString(s.c_str()).GetCString();
404 }
405 }
406 }
407 return NULL;
408}
409
410const char *
411SBPlatform::GetOSDescription()
412{
413 PlatformSP platform_sp(GetSP());
414 if (platform_sp)
415 {
416 std::string s;
417 if (platform_sp->GetOSKernelDescription(s))
418 {
419 if (!s.empty())
420 {
421 // Const-ify the string so we don't need to worry about the lifetime of the string
422 return ConstString(s.c_str()).GetCString();
423 }
424 }
425 }
426 return NULL;
427}
428
429const char *
430SBPlatform::GetHostname ()
431{
432 PlatformSP platform_sp(GetSP());
433 if (platform_sp)
434 return platform_sp->GetHostname();
435 return NULL;
436}
437
438uint32_t
439SBPlatform::GetOSMajorVersion ()
440{
441 uint32_t major, minor, update;
442 PlatformSP platform_sp(GetSP());
443 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
444 return major;
445 return UINT32_MAX;
446
447}
448
449uint32_t
450SBPlatform::GetOSMinorVersion ()
451{
452 uint32_t major, minor, update;
453 PlatformSP platform_sp(GetSP());
454 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
455 return minor;
456 return UINT32_MAX;
457}
458
459uint32_t
460SBPlatform::GetOSUpdateVersion ()
461{
462 uint32_t major, minor, update;
463 PlatformSP platform_sp(GetSP());
464 if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
465 return update;
466 return UINT32_MAX;
467}
468
469SBError
470SBPlatform::Get (SBFileSpec &src,
471 SBFileSpec &dst)
472{
473 SBError sb_error;
474 PlatformSP platform_sp(GetSP());
475 if (platform_sp)
476 {
477 sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
478 }
479 else
480 {
481 sb_error.SetErrorString("invalid platform");
482 }
483 return sb_error;
484}
485
486SBError
487SBPlatform::Put (SBFileSpec &src,
488 SBFileSpec &dst)
489{
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000490 return ExecuteConnected(
491 [&](const lldb::PlatformSP& platform_sp)
492 {
493 if (src.Exists())
494 {
495 uint32_t permissions = src.ref().GetPermissions();
496 if (permissions == 0)
497 {
498 if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory)
499 permissions = eFilePermissionsDirectoryDefault;
500 else
501 permissions = eFilePermissionsFileDefault;
502 }
Greg Claytonfbb76342013-11-20 21:07:01 +0000503
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000504 return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
505 }
506
507 Error error;
508 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
509 return error;
510 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000511}
512
513SBError
514SBPlatform::Install (SBFileSpec &src,
515 SBFileSpec &dst)
516{
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000517 return ExecuteConnected(
518 [&](const lldb::PlatformSP& platform_sp)
519 {
520 if (src.Exists())
521 return platform_sp->Install(src.ref(), dst.ref());
522
523 Error error;
524 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
525 return error;
526 });
Greg Claytonfbb76342013-11-20 21:07:01 +0000527}
528
529
530SBError
531SBPlatform::Run (SBPlatformShellCommand &shell_command)
532{
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000533 return ExecuteConnected(
534 [&](const lldb::PlatformSP& platform_sp)
535 {
536 const char *command = shell_command.GetCommand();
537 if (!command)
538 return Error("invalid shell command (empty)");
539
540 const char *working_dir = shell_command.GetWorkingDirectory();
541 if (working_dir == NULL)
542 {
543 working_dir = platform_sp->GetWorkingDirectory().GetCString();
544 if (working_dir)
545 shell_command.SetWorkingDirectory(working_dir);
546 }
547 return platform_sp->RunShellCommand(command,
Chaoren Lind3173f32015-05-29 19:52:29 +0000548 FileSpec{working_dir, false},
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000549 &shell_command.m_opaque_ptr->m_status,
550 &shell_command.m_opaque_ptr->m_signo,
551 &shell_command.m_opaque_ptr->m_output,
552 shell_command.m_opaque_ptr->m_timeout_sec);
553 });
554}
555
556SBError
557SBPlatform::Launch (SBLaunchInfo &launch_info)
558{
559 return ExecuteConnected(
560 [&](const lldb::PlatformSP& platform_sp)
561 {
562 return platform_sp->LaunchProcess(launch_info.ref());
563 });
564}
565
566SBError
567SBPlatform::Kill (const lldb::pid_t pid)
568{
569 return ExecuteConnected(
570 [&](const lldb::PlatformSP& platform_sp)
571 {
572 return platform_sp->KillProcess(pid);
573 });
574}
575
576SBError
577SBPlatform::ExecuteConnected (const std::function<Error(const lldb::PlatformSP&)>& func)
578{
Greg Claytonfbb76342013-11-20 21:07:01 +0000579 SBError sb_error;
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000580 const auto platform_sp(GetSP());
Greg Claytonfbb76342013-11-20 21:07:01 +0000581 if (platform_sp)
582 {
583 if (platform_sp->IsConnected())
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000584 sb_error.ref() = func(platform_sp);
Greg Claytonfbb76342013-11-20 21:07:01 +0000585 else
Greg Claytonfbb76342013-11-20 21:07:01 +0000586 sb_error.SetErrorString("not connected");
Greg Claytonfbb76342013-11-20 21:07:01 +0000587 }
588 else
Greg Claytonfbb76342013-11-20 21:07:01 +0000589 sb_error.SetErrorString("invalid platform");
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000590
591 return sb_error;
Greg Claytonfbb76342013-11-20 21:07:01 +0000592}
593
594SBError
595SBPlatform::MakeDirectory (const char *path, uint32_t file_permissions)
596{
597 SBError sb_error;
598 PlatformSP platform_sp(GetSP());
599 if (platform_sp)
600 {
Chaoren Lind3173f32015-05-29 19:52:29 +0000601 sb_error.ref() = platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions);
Greg Claytonfbb76342013-11-20 21:07:01 +0000602 }
603 else
604 {
605 sb_error.SetErrorString("invalid platform");
606 }
607 return sb_error;
608}
609
610uint32_t
611SBPlatform::GetFilePermissions (const char *path)
612{
613 PlatformSP platform_sp(GetSP());
614 if (platform_sp)
615 {
616 uint32_t file_permissions = 0;
Chaoren Lind3173f32015-05-29 19:52:29 +0000617 platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions);
Greg Claytonfbb76342013-11-20 21:07:01 +0000618 return file_permissions;
619 }
620 return 0;
621
622}
623
624SBError
625SBPlatform::SetFilePermissions (const char *path, uint32_t file_permissions)
626{
627 SBError sb_error;
628 PlatformSP platform_sp(GetSP());
629 if (platform_sp)
630 {
Chaoren Lind3173f32015-05-29 19:52:29 +0000631 sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false}, file_permissions);
Greg Claytonfbb76342013-11-20 21:07:01 +0000632 }
633 else
634 {
635 sb_error.SetErrorString("invalid platform");
636 }
637 return sb_error;
638
639}
640