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 { 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 //---------------------------------------------------------------------- 54 struct 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 //---------------------------------------------------------------------- 80 SBPlatformConnectOptions::SBPlatformConnectOptions (const char *url) : 81 m_opaque_ptr(new PlatformConnectOptions(url)) 82 { 83 84 } 85 86 SBPlatformConnectOptions::SBPlatformConnectOptions(const SBPlatformConnectOptions &rhs) : 87 m_opaque_ptr(new PlatformConnectOptions()) 88 { 89 *m_opaque_ptr = *rhs.m_opaque_ptr; 90 } 91 92 SBPlatformConnectOptions::~SBPlatformConnectOptions () 93 { 94 delete m_opaque_ptr; 95 } 96 97 void 98 SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) 99 { 100 *m_opaque_ptr = *rhs.m_opaque_ptr; 101 } 102 103 const char * 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 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 121 SBPlatformConnectOptions::GetRsyncEnabled() 122 { 123 return m_opaque_ptr->m_rsync_enabled; 124 } 125 126 void 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 146 SBPlatformConnectOptions::DisableRsync () 147 { 148 m_opaque_ptr->m_rsync_enabled = false; 149 } 150 151 const char * 152 SBPlatformConnectOptions::GetLocalCacheDirectory() 153 { 154 return m_opaque_ptr->m_local_cache_directory.GetCString(); 155 } 156 157 void 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 //---------------------------------------------------------------------- 169 SBPlatformShellCommand::SBPlatformShellCommand (const char *shell_command) : 170 m_opaque_ptr(new PlatformShellCommand(shell_command)) 171 { 172 } 173 174 SBPlatformShellCommand::SBPlatformShellCommand (const SBPlatformShellCommand &rhs) : 175 m_opaque_ptr(new PlatformShellCommand()) 176 { 177 *m_opaque_ptr = *rhs.m_opaque_ptr; 178 } 179 180 SBPlatformShellCommand::~SBPlatformShellCommand() 181 { 182 delete m_opaque_ptr; 183 } 184 185 void 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 * 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 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 * 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 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 228 SBPlatformShellCommand::GetTimeoutSeconds () 229 { 230 return m_opaque_ptr->m_timeout_sec; 231 } 232 233 void 234 SBPlatformShellCommand::SetTimeoutSeconds (uint32_t sec) 235 { 236 m_opaque_ptr->m_timeout_sec = sec; 237 } 238 239 int 240 SBPlatformShellCommand::GetSignal () 241 { 242 return m_opaque_ptr->m_signo; 243 } 244 245 int 246 SBPlatformShellCommand::GetStatus () 247 { 248 return m_opaque_ptr->m_status; 249 } 250 251 const char * 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 //---------------------------------------------------------------------- 262 SBPlatform::SBPlatform () : 263 m_opaque_sp () 264 { 265 266 } 267 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 275 SBPlatform::~SBPlatform() 276 { 277 } 278 279 bool 280 SBPlatform::IsValid () const 281 { 282 return m_opaque_sp.get() != NULL; 283 } 284 285 void 286 SBPlatform::Clear () 287 { 288 m_opaque_sp.reset(); 289 } 290 291 const char * 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 301 SBPlatform::GetSP () const 302 { 303 return m_opaque_sp; 304 } 305 306 void 307 SBPlatform::SetSP (const lldb::PlatformSP& platform_sp) 308 { 309 m_opaque_sp = platform_sp; 310 } 311 312 const char * 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 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 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 355 SBPlatform::DisconnectRemote () 356 { 357 PlatformSP platform_sp(GetSP()); 358 if (platform_sp) 359 platform_sp->DisconnectRemote(); 360 } 361 362 bool 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 * 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 * 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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