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