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 20using namespace lldb; 21using namespace lldb_private; 22 23//---------------------------------------------------------------------- 24// PlatformConnectOptions 25//---------------------------------------------------------------------- 26struct PlatformConnectOptions { 27 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 39 ~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//---------------------------------------------------------------------- 54struct PlatformShellCommand { 55 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 66 ~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//---------------------------------------------------------------------- 80SBPlatformConnectOptions::SBPlatformConnectOptions (const char *url) : 81 m_opaque_ptr(new PlatformConnectOptions(url)) 82{ 83 84} 85 86SBPlatformConnectOptions::SBPlatformConnectOptions(const SBPlatformConnectOptions &rhs) : 87 m_opaque_ptr(new PlatformConnectOptions()) 88{ 89 *m_opaque_ptr = *rhs.m_opaque_ptr; 90} 91 92SBPlatformConnectOptions::~SBPlatformConnectOptions () 93{ 94 delete m_opaque_ptr; 95} 96 97void 98SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) 99{ 100 *m_opaque_ptr = *rhs.m_opaque_ptr; 101} 102 103const char * 104SBPlatformConnectOptions::GetURL() 105{ 106 if (m_opaque_ptr->m_url.empty()) 107 return NULL; 108 return m_opaque_ptr->m_url.c_str(); 109} 110 111void 112SBPlatformConnectOptions::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 120bool 121SBPlatformConnectOptions::GetRsyncEnabled() 122{ 123 return m_opaque_ptr->m_rsync_enabled; 124} 125 126void 127SBPlatformConnectOptions::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 145void 146SBPlatformConnectOptions::DisableRsync () 147{ 148 m_opaque_ptr->m_rsync_enabled = false; 149} 150 151const char * 152SBPlatformConnectOptions::GetLocalCacheDirectory() 153{ 154 return m_opaque_ptr->m_local_cache_directory.GetCString(); 155} 156 157void 158SBPlatformConnectOptions::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//---------------------------------------------------------------------- 169SBPlatformShellCommand::SBPlatformShellCommand (const char *shell_command) : 170 m_opaque_ptr(new PlatformShellCommand(shell_command)) 171{ 172} 173 174SBPlatformShellCommand::SBPlatformShellCommand (const SBPlatformShellCommand &rhs) : 175 m_opaque_ptr(new PlatformShellCommand()) 176{ 177 *m_opaque_ptr = *rhs.m_opaque_ptr; 178} 179 180SBPlatformShellCommand::~SBPlatformShellCommand() 181{ 182 delete m_opaque_ptr; 183} 184 185void 186SBPlatformShellCommand::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 193const char * 194SBPlatformShellCommand::GetCommand() 195{ 196 if (m_opaque_ptr->m_command.empty()) 197 return NULL; 198 return m_opaque_ptr->m_command.c_str(); 199} 200 201void 202SBPlatformShellCommand::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 210const char * 211SBPlatformShellCommand::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 218void 219SBPlatformShellCommand::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 227uint32_t 228SBPlatformShellCommand::GetTimeoutSeconds () 229{ 230 return m_opaque_ptr->m_timeout_sec; 231} 232 233void 234SBPlatformShellCommand::SetTimeoutSeconds (uint32_t sec) 235{ 236 m_opaque_ptr->m_timeout_sec = sec; 237} 238 239int 240SBPlatformShellCommand::GetSignal () 241{ 242 return m_opaque_ptr->m_signo; 243} 244 245int 246SBPlatformShellCommand::GetStatus () 247{ 248 return m_opaque_ptr->m_status; 249} 250 251const char * 252SBPlatformShellCommand::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//---------------------------------------------------------------------- 262SBPlatform::SBPlatform () : 263 m_opaque_sp () 264{ 265 266} 267 268SBPlatform::SBPlatform (const char *platform_name) : 269 m_opaque_sp () 270{ 271 Error error; 272 m_opaque_sp = Platform::Create (platform_name, error); 273} 274 275SBPlatform::~SBPlatform() 276{ 277} 278 279bool 280SBPlatform::IsValid () const 281{ 282 return m_opaque_sp.get() != NULL; 283} 284 285void 286SBPlatform::Clear () 287{ 288 m_opaque_sp.reset(); 289} 290 291const char * 292SBPlatform::GetName () 293{ 294 PlatformSP platform_sp(GetSP()); 295 if (platform_sp) 296 return platform_sp->GetName().GetCString(); 297 return NULL; 298} 299 300lldb::PlatformSP 301SBPlatform::GetSP () const 302{ 303 return m_opaque_sp; 304} 305 306void 307SBPlatform::SetSP (const lldb::PlatformSP& platform_sp) 308{ 309 m_opaque_sp = platform_sp; 310} 311 312const char * 313SBPlatform::GetWorkingDirectory() 314{ 315 PlatformSP platform_sp(GetSP()); 316 if (platform_sp) 317 return platform_sp->GetWorkingDirectory().GetCString(); 318 return NULL; 319} 320 321bool 322SBPlatform::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 336SBError 337SBPlatform::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 354void 355SBPlatform::DisconnectRemote () 356{ 357 PlatformSP platform_sp(GetSP()); 358 if (platform_sp) 359 platform_sp->DisconnectRemote(); 360} 361 362bool 363SBPlatform::IsConnected() 364{ 365 PlatformSP platform_sp(GetSP()); 366 if (platform_sp) 367 platform_sp->IsConnected(); 368 return false; 369} 370 371const char * 372SBPlatform::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 387const char * 388SBPlatform::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 406const char * 407SBPlatform::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 425const char * 426SBPlatform::GetHostname () 427{ 428 PlatformSP platform_sp(GetSP()); 429 if (platform_sp) 430 return platform_sp->GetHostname(); 431 return NULL; 432} 433 434uint32_t 435SBPlatform::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 445uint32_t 446SBPlatform::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 455uint32_t 456SBPlatform::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 465SBError 466SBPlatform::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 482SBError 483SBPlatform::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 518SBError 519SBPlatform::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 543SBError 544SBPlatform::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 586SBError 587SBPlatform::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 602uint32_t 603SBPlatform::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 616SBError 617SBPlatform::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