1e0f8f574SDaniel Malea //===-- PlatformPOSIX.cpp ---------------------------------------*- C++ -*-===// 2e0f8f574SDaniel Malea // 3e0f8f574SDaniel Malea // The LLVM Compiler Infrastructure 4e0f8f574SDaniel Malea // 5e0f8f574SDaniel Malea // This file is distributed under the University of Illinois Open Source 6e0f8f574SDaniel Malea // License. See LICENSE.TXT for details. 7e0f8f574SDaniel Malea // 8e0f8f574SDaniel Malea //===----------------------------------------------------------------------===// 9e0f8f574SDaniel Malea 10e0f8f574SDaniel Malea #include "PlatformPOSIX.h" 11e0f8f574SDaniel Malea 12e0f8f574SDaniel Malea // C Includes 13e0f8f574SDaniel Malea // C++ Includes 14e0f8f574SDaniel Malea // Other libraries and framework includes 15e0f8f574SDaniel Malea // Project includes 16e0f8f574SDaniel Malea 17e0f8f574SDaniel Malea #include "lldb/Core/DataBufferHeap.h" 18348fb385STodd Fiala #include "lldb/Core/Debugger.h" 19e0f8f574SDaniel Malea #include "lldb/Core/Log.h" 20348fb385STodd Fiala #include "lldb/Core/Module.h" 21e0f8f574SDaniel Malea #include "lldb/Core/StreamString.h" 22e0f8f574SDaniel Malea #include "lldb/Host/File.h" 23c00cf4a0SZachary Turner #include "lldb/Host/FileCache.h" 24e0f8f574SDaniel Malea #include "lldb/Host/FileSpec.h" 25c00cf4a0SZachary Turner #include "lldb/Host/FileSystem.h" 26e0f8f574SDaniel Malea #include "lldb/Host/Host.h" 27015d818bSTodd Fiala #include "lldb/Target/ProcessLaunchInfo.h" 28e0f8f574SDaniel Malea 29e0f8f574SDaniel Malea using namespace lldb; 30e0f8f574SDaniel Malea using namespace lldb_private; 31e0f8f574SDaniel Malea 32e0f8f574SDaniel Malea 33e0f8f574SDaniel Malea //------------------------------------------------------------------ 34e0f8f574SDaniel Malea /// Default Constructor 35e0f8f574SDaniel Malea //------------------------------------------------------------------ 36e0f8f574SDaniel Malea PlatformPOSIX::PlatformPOSIX (bool is_host) : 37e0f8f574SDaniel Malea Platform(is_host), // This is the local host platform 38e0f8f574SDaniel Malea m_remote_platform_sp () 39e0f8f574SDaniel Malea { 40e0f8f574SDaniel Malea } 41e0f8f574SDaniel Malea 42e0f8f574SDaniel Malea //------------------------------------------------------------------ 43e0f8f574SDaniel Malea /// Destructor. 44e0f8f574SDaniel Malea /// 45e0f8f574SDaniel Malea /// The destructor is virtual since this class is designed to be 46e0f8f574SDaniel Malea /// inherited from by the plug-in instance. 47e0f8f574SDaniel Malea //------------------------------------------------------------------ 48e0f8f574SDaniel Malea PlatformPOSIX::~PlatformPOSIX() 49e0f8f574SDaniel Malea { 50e0f8f574SDaniel Malea } 51e0f8f574SDaniel Malea 52e0f8f574SDaniel Malea lldb_private::OptionGroupOptions* 53e0f8f574SDaniel Malea PlatformPOSIX::GetConnectionOptions (lldb_private::CommandInterpreter& interpreter) 54e0f8f574SDaniel Malea { 55e0f8f574SDaniel Malea if (m_options.get() == NULL) 56e0f8f574SDaniel Malea { 57e0f8f574SDaniel Malea m_options.reset(new OptionGroupOptions(interpreter)); 58e0f8f574SDaniel Malea m_options->Append(new OptionGroupPlatformRSync()); 59e0f8f574SDaniel Malea m_options->Append(new OptionGroupPlatformSSH()); 60e0f8f574SDaniel Malea m_options->Append(new OptionGroupPlatformCaching()); 61e0f8f574SDaniel Malea } 62e0f8f574SDaniel Malea return m_options.get(); 63e0f8f574SDaniel Malea } 64e0f8f574SDaniel Malea 65015d818bSTodd Fiala bool 66015d818bSTodd Fiala PlatformPOSIX::IsConnected () const 67015d818bSTodd Fiala { 68015d818bSTodd Fiala if (IsHost()) 69015d818bSTodd Fiala return true; 70015d818bSTodd Fiala else if (m_remote_platform_sp) 71015d818bSTodd Fiala return m_remote_platform_sp->IsConnected(); 72015d818bSTodd Fiala return false; 73015d818bSTodd Fiala } 74015d818bSTodd Fiala 75e0f8f574SDaniel Malea lldb_private::Error 76e0f8f574SDaniel Malea PlatformPOSIX::RunShellCommand (const char *command, // Shouldn't be NULL 77e0f8f574SDaniel Malea const char *working_dir, // Pass NULL to use the current working directory 78e0f8f574SDaniel Malea int *status_ptr, // Pass NULL if you don't want the process exit status 79e0f8f574SDaniel Malea int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit 80e0f8f574SDaniel Malea std::string *command_output, // Pass NULL if you don't want the command output 81e0f8f574SDaniel Malea uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish 82e0f8f574SDaniel Malea { 83e0f8f574SDaniel Malea if (IsHost()) 84e0f8f574SDaniel Malea return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 85e0f8f574SDaniel Malea else 86e0f8f574SDaniel Malea { 87e0f8f574SDaniel Malea if (m_remote_platform_sp) 88e0f8f574SDaniel Malea return m_remote_platform_sp->RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 89e0f8f574SDaniel Malea else 90e0f8f574SDaniel Malea return Error("unable to run a remote command without a platform"); 91e0f8f574SDaniel Malea } 92e0f8f574SDaniel Malea } 93e0f8f574SDaniel Malea 94fbb76349SGreg Clayton Error 95fbb76349SGreg Clayton PlatformPOSIX::MakeDirectory (const char *path, uint32_t file_permissions) 96e0f8f574SDaniel Malea { 97fbb76349SGreg Clayton if (m_remote_platform_sp) 98fbb76349SGreg Clayton return m_remote_platform_sp->MakeDirectory(path, file_permissions); 99fbb76349SGreg Clayton else 100fbb76349SGreg Clayton return Platform::MakeDirectory(path ,file_permissions); 101e0f8f574SDaniel Malea } 102fbb76349SGreg Clayton 103fbb76349SGreg Clayton Error 104fbb76349SGreg Clayton PlatformPOSIX::GetFilePermissions (const char *path, uint32_t &file_permissions) 105fbb76349SGreg Clayton { 106fbb76349SGreg Clayton if (m_remote_platform_sp) 107fbb76349SGreg Clayton return m_remote_platform_sp->GetFilePermissions(path, file_permissions); 108fbb76349SGreg Clayton else 109fbb76349SGreg Clayton return Platform::GetFilePermissions(path ,file_permissions); 110fbb76349SGreg Clayton } 111fbb76349SGreg Clayton 112fbb76349SGreg Clayton Error 113fbb76349SGreg Clayton PlatformPOSIX::SetFilePermissions (const char *path, uint32_t file_permissions) 114fbb76349SGreg Clayton { 115fbb76349SGreg Clayton if (m_remote_platform_sp) 1161cfb98abSZachary Turner return m_remote_platform_sp->SetFilePermissions(path, file_permissions); 117fbb76349SGreg Clayton else 118fbb76349SGreg Clayton return Platform::SetFilePermissions(path ,file_permissions); 119e0f8f574SDaniel Malea } 120e0f8f574SDaniel Malea 121e0f8f574SDaniel Malea lldb::user_id_t 122e0f8f574SDaniel Malea PlatformPOSIX::OpenFile (const FileSpec& file_spec, 123e0f8f574SDaniel Malea uint32_t flags, 124fbb76349SGreg Clayton uint32_t mode, 125e0f8f574SDaniel Malea Error &error) 126e0f8f574SDaniel Malea { 127e0f8f574SDaniel Malea if (IsHost()) 128c00cf4a0SZachary Turner return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error); 129fbb76349SGreg Clayton else if (m_remote_platform_sp) 130e0f8f574SDaniel Malea return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error); 131fbb76349SGreg Clayton else 132e0f8f574SDaniel Malea return Platform::OpenFile(file_spec, flags, mode, error); 133e0f8f574SDaniel Malea } 134e0f8f574SDaniel Malea 135e0f8f574SDaniel Malea bool 136e0f8f574SDaniel Malea PlatformPOSIX::CloseFile (lldb::user_id_t fd, Error &error) 137e0f8f574SDaniel Malea { 138e0f8f574SDaniel Malea if (IsHost()) 139c00cf4a0SZachary Turner return FileCache::GetInstance().CloseFile(fd, error); 140fbb76349SGreg Clayton else if (m_remote_platform_sp) 141e0f8f574SDaniel Malea return m_remote_platform_sp->CloseFile(fd, error); 142fbb76349SGreg Clayton else 143e0f8f574SDaniel Malea return Platform::CloseFile(fd, error); 144e0f8f574SDaniel Malea } 145e0f8f574SDaniel Malea 146e0f8f574SDaniel Malea uint64_t 147e0f8f574SDaniel Malea PlatformPOSIX::ReadFile (lldb::user_id_t fd, 148e0f8f574SDaniel Malea uint64_t offset, 149e0f8f574SDaniel Malea void *dst, 150e0f8f574SDaniel Malea uint64_t dst_len, 151e0f8f574SDaniel Malea Error &error) 152e0f8f574SDaniel Malea { 153e0f8f574SDaniel Malea if (IsHost()) 154c00cf4a0SZachary Turner return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error); 155fbb76349SGreg Clayton else if (m_remote_platform_sp) 156e0f8f574SDaniel Malea return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error); 157fbb76349SGreg Clayton else 158e0f8f574SDaniel Malea return Platform::ReadFile(fd, offset, dst, dst_len, error); 159e0f8f574SDaniel Malea } 160e0f8f574SDaniel Malea 161e0f8f574SDaniel Malea uint64_t 162e0f8f574SDaniel Malea PlatformPOSIX::WriteFile (lldb::user_id_t fd, 163e0f8f574SDaniel Malea uint64_t offset, 164e0f8f574SDaniel Malea const void* src, 165e0f8f574SDaniel Malea uint64_t src_len, 166e0f8f574SDaniel Malea Error &error) 167e0f8f574SDaniel Malea { 168e0f8f574SDaniel Malea if (IsHost()) 169c00cf4a0SZachary Turner return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error); 170fbb76349SGreg Clayton else if (m_remote_platform_sp) 171e0f8f574SDaniel Malea return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error); 172fbb76349SGreg Clayton else 173e0f8f574SDaniel Malea return Platform::WriteFile(fd, offset, src, src_len, error); 174e0f8f574SDaniel Malea } 175e0f8f574SDaniel Malea 176e0f8f574SDaniel Malea static uint32_t 177e0f8f574SDaniel Malea chown_file(Platform *platform, 178e0f8f574SDaniel Malea const char* path, 179e0f8f574SDaniel Malea uint32_t uid = UINT32_MAX, 180e0f8f574SDaniel Malea uint32_t gid = UINT32_MAX) 181e0f8f574SDaniel Malea { 182e0f8f574SDaniel Malea if (!platform || !path || *path == 0) 183e0f8f574SDaniel Malea return UINT32_MAX; 184e0f8f574SDaniel Malea 185e0f8f574SDaniel Malea if (uid == UINT32_MAX && gid == UINT32_MAX) 186e0f8f574SDaniel Malea return 0; // pretend I did chown correctly - actually I just didn't care 187e0f8f574SDaniel Malea 188e0f8f574SDaniel Malea StreamString command; 189e0f8f574SDaniel Malea command.PutCString("chown "); 190e0f8f574SDaniel Malea if (uid != UINT32_MAX) 191e0f8f574SDaniel Malea command.Printf("%d",uid); 192e0f8f574SDaniel Malea if (gid != UINT32_MAX) 193e0f8f574SDaniel Malea command.Printf(":%d",gid); 194e0f8f574SDaniel Malea command.Printf("%s",path); 195e0f8f574SDaniel Malea int status; 196e0f8f574SDaniel Malea platform->RunShellCommand(command.GetData(), 197e0f8f574SDaniel Malea NULL, 198e0f8f574SDaniel Malea &status, 199e0f8f574SDaniel Malea NULL, 200e0f8f574SDaniel Malea NULL, 201e0f8f574SDaniel Malea 10); 202e0f8f574SDaniel Malea return status; 203e0f8f574SDaniel Malea } 204e0f8f574SDaniel Malea 205e0f8f574SDaniel Malea lldb_private::Error 206e0f8f574SDaniel Malea PlatformPOSIX::PutFile (const lldb_private::FileSpec& source, 207e0f8f574SDaniel Malea const lldb_private::FileSpec& destination, 208e0f8f574SDaniel Malea uint32_t uid, 209e0f8f574SDaniel Malea uint32_t gid) 210e0f8f574SDaniel Malea { 211fbb76349SGreg Clayton Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 212fbb76349SGreg Clayton 213e0f8f574SDaniel Malea if (IsHost()) 214e0f8f574SDaniel Malea { 215e0f8f574SDaniel Malea if (FileSpec::Equal(source, destination, true)) 216e0f8f574SDaniel Malea return Error(); 217e0f8f574SDaniel Malea // cp src dst 218e0f8f574SDaniel Malea // chown uid:gid dst 219e0f8f574SDaniel Malea std::string src_path (source.GetPath()); 220e0f8f574SDaniel Malea if (src_path.empty()) 221e0f8f574SDaniel Malea return Error("unable to get file path for source"); 222e0f8f574SDaniel Malea std::string dst_path (destination.GetPath()); 223e0f8f574SDaniel Malea if (dst_path.empty()) 224e0f8f574SDaniel Malea return Error("unable to get file path for destination"); 225e0f8f574SDaniel Malea StreamString command; 226e0f8f574SDaniel Malea command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str()); 227e0f8f574SDaniel Malea int status; 228e0f8f574SDaniel Malea RunShellCommand(command.GetData(), 229e0f8f574SDaniel Malea NULL, 230e0f8f574SDaniel Malea &status, 231e0f8f574SDaniel Malea NULL, 232e0f8f574SDaniel Malea NULL, 233e0f8f574SDaniel Malea 10); 234e0f8f574SDaniel Malea if (status != 0) 235e0f8f574SDaniel Malea return Error("unable to perform copy"); 236e0f8f574SDaniel Malea if (uid == UINT32_MAX && gid == UINT32_MAX) 237e0f8f574SDaniel Malea return Error(); 238e0f8f574SDaniel Malea if (chown_file(this,dst_path.c_str(),uid,gid) != 0) 239e0f8f574SDaniel Malea return Error("unable to perform chown"); 240e0f8f574SDaniel Malea return Error(); 241e0f8f574SDaniel Malea } 242fbb76349SGreg Clayton else if (m_remote_platform_sp) 243e0f8f574SDaniel Malea { 244e0f8f574SDaniel Malea if (GetSupportsRSync()) 245e0f8f574SDaniel Malea { 246e0f8f574SDaniel Malea std::string src_path (source.GetPath()); 247e0f8f574SDaniel Malea if (src_path.empty()) 248e0f8f574SDaniel Malea return Error("unable to get file path for source"); 249e0f8f574SDaniel Malea std::string dst_path (destination.GetPath()); 250e0f8f574SDaniel Malea if (dst_path.empty()) 251e0f8f574SDaniel Malea return Error("unable to get file path for destination"); 252e0f8f574SDaniel Malea StreamString command; 253e0f8f574SDaniel Malea if (GetIgnoresRemoteHostname()) 254e0f8f574SDaniel Malea { 255e0f8f574SDaniel Malea if (!GetRSyncPrefix()) 256e0f8f574SDaniel Malea command.Printf("rsync %s %s %s", 257e0f8f574SDaniel Malea GetRSyncOpts(), 258e0f8f574SDaniel Malea src_path.c_str(), 259e0f8f574SDaniel Malea dst_path.c_str()); 260e0f8f574SDaniel Malea else 261e0f8f574SDaniel Malea command.Printf("rsync %s %s %s%s", 262e0f8f574SDaniel Malea GetRSyncOpts(), 263e0f8f574SDaniel Malea src_path.c_str(), 264e0f8f574SDaniel Malea GetRSyncPrefix(), 265e0f8f574SDaniel Malea dst_path.c_str()); 266e0f8f574SDaniel Malea } 267e0f8f574SDaniel Malea else 268e0f8f574SDaniel Malea command.Printf("rsync %s %s %s:%s", 269e0f8f574SDaniel Malea GetRSyncOpts(), 270e0f8f574SDaniel Malea src_path.c_str(), 271e0f8f574SDaniel Malea GetHostname(), 272e0f8f574SDaniel Malea dst_path.c_str()); 273e0f8f574SDaniel Malea if (log) 274e0f8f574SDaniel Malea log->Printf("[PutFile] Running command: %s\n", command.GetData()); 275e0f8f574SDaniel Malea int retcode; 276e0f8f574SDaniel Malea Host::RunShellCommand(command.GetData(), 277e0f8f574SDaniel Malea NULL, 278e0f8f574SDaniel Malea &retcode, 279e0f8f574SDaniel Malea NULL, 280e0f8f574SDaniel Malea NULL, 281e0f8f574SDaniel Malea 60); 282e0f8f574SDaniel Malea if (retcode == 0) 283e0f8f574SDaniel Malea { 284e0f8f574SDaniel Malea // Don't chown a local file for a remote system 285e0f8f574SDaniel Malea // if (chown_file(this,dst_path.c_str(),uid,gid) != 0) 286e0f8f574SDaniel Malea // return Error("unable to perform chown"); 287e0f8f574SDaniel Malea return Error(); 288e0f8f574SDaniel Malea } 289e0f8f574SDaniel Malea // if we are still here rsync has failed - let's try the slow way before giving up 290e0f8f574SDaniel Malea } 291e0f8f574SDaniel Malea } 292e0f8f574SDaniel Malea return Platform::PutFile(source,destination,uid,gid); 293e0f8f574SDaniel Malea } 294e0f8f574SDaniel Malea 295e0f8f574SDaniel Malea lldb::user_id_t 296e0f8f574SDaniel Malea PlatformPOSIX::GetFileSize (const FileSpec& file_spec) 297e0f8f574SDaniel Malea { 298e0f8f574SDaniel Malea if (IsHost()) 299c00cf4a0SZachary Turner return FileSystem::GetFileSize(file_spec); 300fbb76349SGreg Clayton else if (m_remote_platform_sp) 301e0f8f574SDaniel Malea return m_remote_platform_sp->GetFileSize(file_spec); 302fbb76349SGreg Clayton else 303e0f8f574SDaniel Malea return Platform::GetFileSize(file_spec); 304e0f8f574SDaniel Malea } 305e0f8f574SDaniel Malea 306fbb76349SGreg Clayton Error 307fbb76349SGreg Clayton PlatformPOSIX::CreateSymlink(const char *src, const char *dst) 308fbb76349SGreg Clayton { 309fbb76349SGreg Clayton if (IsHost()) 310c00cf4a0SZachary Turner return FileSystem::Symlink(src, dst); 311fbb76349SGreg Clayton else if (m_remote_platform_sp) 312fbb76349SGreg Clayton return m_remote_platform_sp->CreateSymlink(src, dst); 313fbb76349SGreg Clayton else 314fbb76349SGreg Clayton return Platform::CreateSymlink(src, dst); 315fbb76349SGreg Clayton } 316fbb76349SGreg Clayton 317e0f8f574SDaniel Malea bool 318e0f8f574SDaniel Malea PlatformPOSIX::GetFileExists (const FileSpec& file_spec) 319e0f8f574SDaniel Malea { 320e0f8f574SDaniel Malea if (IsHost()) 321e0f8f574SDaniel Malea return file_spec.Exists(); 322fbb76349SGreg Clayton else if (m_remote_platform_sp) 323e0f8f574SDaniel Malea return m_remote_platform_sp->GetFileExists(file_spec); 324fbb76349SGreg Clayton else 325e0f8f574SDaniel Malea return Platform::GetFileExists(file_spec); 326e0f8f574SDaniel Malea } 327e0f8f574SDaniel Malea 328fbb76349SGreg Clayton Error 329fbb76349SGreg Clayton PlatformPOSIX::Unlink (const char *path) 330e0f8f574SDaniel Malea { 331e0f8f574SDaniel Malea if (IsHost()) 332c00cf4a0SZachary Turner return FileSystem::Unlink(path); 333fbb76349SGreg Clayton else if (m_remote_platform_sp) 334fbb76349SGreg Clayton return m_remote_platform_sp->Unlink(path); 335fbb76349SGreg Clayton else 336fbb76349SGreg Clayton return Platform::Unlink(path); 337e0f8f574SDaniel Malea } 338e0f8f574SDaniel Malea 339e0f8f574SDaniel Malea lldb_private::Error 340e0f8f574SDaniel Malea PlatformPOSIX::GetFile (const lldb_private::FileSpec& source /* remote file path */, 341e0f8f574SDaniel Malea const lldb_private::FileSpec& destination /* local file path */) 342e0f8f574SDaniel Malea { 343fbb76349SGreg Clayton Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 344fbb76349SGreg Clayton 345e0f8f574SDaniel Malea // Check the args, first. 346e0f8f574SDaniel Malea std::string src_path (source.GetPath()); 347e0f8f574SDaniel Malea if (src_path.empty()) 348e0f8f574SDaniel Malea return Error("unable to get file path for source"); 349e0f8f574SDaniel Malea std::string dst_path (destination.GetPath()); 350e0f8f574SDaniel Malea if (dst_path.empty()) 351e0f8f574SDaniel Malea return Error("unable to get file path for destination"); 352e0f8f574SDaniel Malea if (IsHost()) 353e0f8f574SDaniel Malea { 354e0f8f574SDaniel Malea if (FileSpec::Equal(source, destination, true)) 355e0f8f574SDaniel Malea return Error("local scenario->source and destination are the same file path: no operation performed"); 356e0f8f574SDaniel Malea // cp src dst 357e0f8f574SDaniel Malea StreamString cp_command; 358e0f8f574SDaniel Malea cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str()); 359e0f8f574SDaniel Malea int status; 360e0f8f574SDaniel Malea RunShellCommand(cp_command.GetData(), 361e0f8f574SDaniel Malea NULL, 362e0f8f574SDaniel Malea &status, 363e0f8f574SDaniel Malea NULL, 364e0f8f574SDaniel Malea NULL, 365e0f8f574SDaniel Malea 10); 366e0f8f574SDaniel Malea if (status != 0) 367e0f8f574SDaniel Malea return Error("unable to perform copy"); 368e0f8f574SDaniel Malea return Error(); 369e0f8f574SDaniel Malea } 370fbb76349SGreg Clayton else if (m_remote_platform_sp) 371e0f8f574SDaniel Malea { 372e0f8f574SDaniel Malea if (GetSupportsRSync()) 373e0f8f574SDaniel Malea { 374e0f8f574SDaniel Malea StreamString command; 375e0f8f574SDaniel Malea if (GetIgnoresRemoteHostname()) 376e0f8f574SDaniel Malea { 377e0f8f574SDaniel Malea if (!GetRSyncPrefix()) 378e0f8f574SDaniel Malea command.Printf("rsync %s %s %s", 379e0f8f574SDaniel Malea GetRSyncOpts(), 380e0f8f574SDaniel Malea src_path.c_str(), 381e0f8f574SDaniel Malea dst_path.c_str()); 382e0f8f574SDaniel Malea else 383e0f8f574SDaniel Malea command.Printf("rsync %s %s%s %s", 384e0f8f574SDaniel Malea GetRSyncOpts(), 385e0f8f574SDaniel Malea GetRSyncPrefix(), 386e0f8f574SDaniel Malea src_path.c_str(), 387e0f8f574SDaniel Malea dst_path.c_str()); 388e0f8f574SDaniel Malea } 389e0f8f574SDaniel Malea else 390e0f8f574SDaniel Malea command.Printf("rsync %s %s:%s %s", 391e0f8f574SDaniel Malea GetRSyncOpts(), 392e0f8f574SDaniel Malea m_remote_platform_sp->GetHostname(), 393e0f8f574SDaniel Malea src_path.c_str(), 394e0f8f574SDaniel Malea dst_path.c_str()); 395e0f8f574SDaniel Malea if (log) 396e0f8f574SDaniel Malea log->Printf("[GetFile] Running command: %s\n", command.GetData()); 397e0f8f574SDaniel Malea int retcode; 398e0f8f574SDaniel Malea Host::RunShellCommand(command.GetData(), 399e0f8f574SDaniel Malea NULL, 400e0f8f574SDaniel Malea &retcode, 401e0f8f574SDaniel Malea NULL, 402e0f8f574SDaniel Malea NULL, 403e0f8f574SDaniel Malea 60); 404e0f8f574SDaniel Malea if (retcode == 0) 405e0f8f574SDaniel Malea return Error(); 406e0f8f574SDaniel Malea // If we are here, rsync has failed - let's try the slow way before giving up 407e0f8f574SDaniel Malea } 408e0f8f574SDaniel Malea // open src and dst 409e0f8f574SDaniel Malea // read/write, read/write, read/write, ... 410e0f8f574SDaniel Malea // close src 411e0f8f574SDaniel Malea // close dst 412e0f8f574SDaniel Malea if (log) 413e0f8f574SDaniel Malea log->Printf("[GetFile] Using block by block transfer....\n"); 414e0f8f574SDaniel Malea Error error; 415e0f8f574SDaniel Malea user_id_t fd_src = OpenFile (source, 416e0f8f574SDaniel Malea File::eOpenOptionRead, 417fbb76349SGreg Clayton lldb::eFilePermissionsFileDefault, 418e0f8f574SDaniel Malea error); 419e0f8f574SDaniel Malea 420e0f8f574SDaniel Malea if (fd_src == UINT64_MAX) 421e0f8f574SDaniel Malea return Error("unable to open source file"); 422e0f8f574SDaniel Malea 423fbb76349SGreg Clayton uint32_t permissions = 0; 424fbb76349SGreg Clayton error = GetFilePermissions(source.GetPath().c_str(), permissions); 425e0f8f574SDaniel Malea 426e0f8f574SDaniel Malea if (permissions == 0) 427fbb76349SGreg Clayton permissions = lldb::eFilePermissionsFileDefault; 428e0f8f574SDaniel Malea 429c00cf4a0SZachary Turner user_id_t fd_dst = FileCache::GetInstance().OpenFile( 430c00cf4a0SZachary Turner destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, permissions, 431e0f8f574SDaniel Malea error); 432e0f8f574SDaniel Malea 433e0f8f574SDaniel Malea if (fd_dst == UINT64_MAX) 434e0f8f574SDaniel Malea { 435e0f8f574SDaniel Malea if (error.Success()) 436e0f8f574SDaniel Malea error.SetErrorString("unable to open destination file"); 437e0f8f574SDaniel Malea } 438e0f8f574SDaniel Malea 439e0f8f574SDaniel Malea if (error.Success()) 440e0f8f574SDaniel Malea { 441e0f8f574SDaniel Malea lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); 442e0f8f574SDaniel Malea uint64_t offset = 0; 443e0f8f574SDaniel Malea error.Clear(); 444e0f8f574SDaniel Malea while (error.Success()) 445e0f8f574SDaniel Malea { 446e0f8f574SDaniel Malea const uint64_t n_read = ReadFile (fd_src, 447e0f8f574SDaniel Malea offset, 448e0f8f574SDaniel Malea buffer_sp->GetBytes(), 449e0f8f574SDaniel Malea buffer_sp->GetByteSize(), 450e0f8f574SDaniel Malea error); 451e0f8f574SDaniel Malea if (error.Fail()) 452e0f8f574SDaniel Malea break; 453e0f8f574SDaniel Malea if (n_read == 0) 454e0f8f574SDaniel Malea break; 455c00cf4a0SZachary Turner if (FileCache::GetInstance().WriteFile(fd_dst, offset, buffer_sp->GetBytes(), n_read, error) != n_read) 456e0f8f574SDaniel Malea { 457e0f8f574SDaniel Malea if (!error.Fail()) 458e0f8f574SDaniel Malea error.SetErrorString("unable to write to destination file"); 459e0f8f574SDaniel Malea break; 460e0f8f574SDaniel Malea } 461e0f8f574SDaniel Malea offset += n_read; 462e0f8f574SDaniel Malea } 463e0f8f574SDaniel Malea } 464e0f8f574SDaniel Malea // Ignore the close error of src. 465e0f8f574SDaniel Malea if (fd_src != UINT64_MAX) 466e0f8f574SDaniel Malea CloseFile(fd_src, error); 467e0f8f574SDaniel Malea // And close the dst file descriptot. 468c00cf4a0SZachary Turner if (fd_dst != UINT64_MAX && !FileCache::GetInstance().CloseFile(fd_dst, error)) 469e0f8f574SDaniel Malea { 470e0f8f574SDaniel Malea if (!error.Fail()) 471e0f8f574SDaniel Malea error.SetErrorString("unable to close destination file"); 472e0f8f574SDaniel Malea 473e0f8f574SDaniel Malea } 474e0f8f574SDaniel Malea return error; 475e0f8f574SDaniel Malea } 476e0f8f574SDaniel Malea return Platform::GetFile(source,destination); 477e0f8f574SDaniel Malea } 478e0f8f574SDaniel Malea 479e0f8f574SDaniel Malea std::string 480e0f8f574SDaniel Malea PlatformPOSIX::GetPlatformSpecificConnectionInformation() 481e0f8f574SDaniel Malea { 482e0f8f574SDaniel Malea StreamString stream; 483e0f8f574SDaniel Malea if (GetSupportsRSync()) 484e0f8f574SDaniel Malea { 485e0f8f574SDaniel Malea stream.PutCString("rsync"); 486e0f8f574SDaniel Malea if ( (GetRSyncOpts() && *GetRSyncOpts()) || 487e0f8f574SDaniel Malea (GetRSyncPrefix() && *GetRSyncPrefix()) || 488e0f8f574SDaniel Malea GetIgnoresRemoteHostname()) 489e0f8f574SDaniel Malea { 490e0f8f574SDaniel Malea stream.Printf(", options: "); 491e0f8f574SDaniel Malea if (GetRSyncOpts() && *GetRSyncOpts()) 492e0f8f574SDaniel Malea stream.Printf("'%s' ",GetRSyncOpts()); 493e0f8f574SDaniel Malea stream.Printf(", prefix: "); 494e0f8f574SDaniel Malea if (GetRSyncPrefix() && *GetRSyncPrefix()) 495e0f8f574SDaniel Malea stream.Printf("'%s' ",GetRSyncPrefix()); 496e0f8f574SDaniel Malea if (GetIgnoresRemoteHostname()) 497e0f8f574SDaniel Malea stream.Printf("ignore remote-hostname "); 498e0f8f574SDaniel Malea } 499e0f8f574SDaniel Malea } 500e0f8f574SDaniel Malea if (GetSupportsSSH()) 501e0f8f574SDaniel Malea { 502e0f8f574SDaniel Malea stream.PutCString("ssh"); 503e0f8f574SDaniel Malea if (GetSSHOpts() && *GetSSHOpts()) 504e0f8f574SDaniel Malea stream.Printf(", options: '%s' ",GetSSHOpts()); 505e0f8f574SDaniel Malea } 506e0f8f574SDaniel Malea if (GetLocalCacheDirectory() && *GetLocalCacheDirectory()) 507e0f8f574SDaniel Malea stream.Printf("cache dir: %s",GetLocalCacheDirectory()); 508e0f8f574SDaniel Malea if (stream.GetSize()) 509e0f8f574SDaniel Malea return stream.GetData(); 510e0f8f574SDaniel Malea else 511e0f8f574SDaniel Malea return ""; 512e0f8f574SDaniel Malea } 513e0f8f574SDaniel Malea 514e0f8f574SDaniel Malea bool 515e0f8f574SDaniel Malea PlatformPOSIX::CalculateMD5 (const FileSpec& file_spec, 516e0f8f574SDaniel Malea uint64_t &low, 517e0f8f574SDaniel Malea uint64_t &high) 518e0f8f574SDaniel Malea { 519e0f8f574SDaniel Malea if (IsHost()) 520e0f8f574SDaniel Malea return Platform::CalculateMD5 (file_spec, low, high); 521e0f8f574SDaniel Malea if (m_remote_platform_sp) 522e0f8f574SDaniel Malea return m_remote_platform_sp->CalculateMD5(file_spec, low, high); 523e0f8f574SDaniel Malea return false; 524e0f8f574SDaniel Malea } 525fbb76349SGreg Clayton 526fbb76349SGreg Clayton lldb_private::ConstString 527fbb76349SGreg Clayton PlatformPOSIX::GetRemoteWorkingDirectory() 528fbb76349SGreg Clayton { 529fbb76349SGreg Clayton if (IsRemote() && m_remote_platform_sp) 530fbb76349SGreg Clayton return m_remote_platform_sp->GetRemoteWorkingDirectory(); 531fbb76349SGreg Clayton else 532fbb76349SGreg Clayton return Platform::GetRemoteWorkingDirectory(); 533fbb76349SGreg Clayton } 534fbb76349SGreg Clayton 535fbb76349SGreg Clayton bool 536fbb76349SGreg Clayton PlatformPOSIX::SetRemoteWorkingDirectory(const lldb_private::ConstString &path) 537fbb76349SGreg Clayton { 538fbb76349SGreg Clayton if (IsRemote() && m_remote_platform_sp) 539fbb76349SGreg Clayton return m_remote_platform_sp->SetRemoteWorkingDirectory(path); 540fbb76349SGreg Clayton else 541fbb76349SGreg Clayton return Platform::SetRemoteWorkingDirectory(path); 542fbb76349SGreg Clayton } 543fbb76349SGreg Clayton 544015d818bSTodd Fiala bool 545015d818bSTodd Fiala PlatformPOSIX::GetRemoteOSVersion () 546015d818bSTodd Fiala { 547015d818bSTodd Fiala if (m_remote_platform_sp) 548015d818bSTodd Fiala return m_remote_platform_sp->GetOSVersion (m_major_os_version, 549015d818bSTodd Fiala m_minor_os_version, 550015d818bSTodd Fiala m_update_os_version); 551015d818bSTodd Fiala return false; 552015d818bSTodd Fiala } 553015d818bSTodd Fiala 554015d818bSTodd Fiala bool 555015d818bSTodd Fiala PlatformPOSIX::GetRemoteOSBuildString (std::string &s) 556015d818bSTodd Fiala { 557015d818bSTodd Fiala if (m_remote_platform_sp) 558015d818bSTodd Fiala return m_remote_platform_sp->GetRemoteOSBuildString (s); 559015d818bSTodd Fiala s.clear(); 560015d818bSTodd Fiala return false; 561015d818bSTodd Fiala } 562015d818bSTodd Fiala 563e15fcaa2STodd Fiala size_t 564e15fcaa2STodd Fiala PlatformPOSIX::GetEnvironment (StringList &env) 565e15fcaa2STodd Fiala { 566e15fcaa2STodd Fiala if (IsRemote()) 567e15fcaa2STodd Fiala { 568e15fcaa2STodd Fiala if (m_remote_platform_sp) 569e15fcaa2STodd Fiala return m_remote_platform_sp->GetEnvironment(env); 570e15fcaa2STodd Fiala return 0; 571e15fcaa2STodd Fiala } 572e15fcaa2STodd Fiala return Host::GetEnvironment(env); 573e15fcaa2STodd Fiala } 574e15fcaa2STodd Fiala 575015d818bSTodd Fiala bool 576015d818bSTodd Fiala PlatformPOSIX::GetRemoteOSKernelDescription (std::string &s) 577015d818bSTodd Fiala { 578015d818bSTodd Fiala if (m_remote_platform_sp) 579015d818bSTodd Fiala return m_remote_platform_sp->GetRemoteOSKernelDescription (s); 580015d818bSTodd Fiala s.clear(); 581015d818bSTodd Fiala return false; 582015d818bSTodd Fiala } 583015d818bSTodd Fiala 584015d818bSTodd Fiala // Remote Platform subclasses need to override this function 585015d818bSTodd Fiala ArchSpec 586015d818bSTodd Fiala PlatformPOSIX::GetRemoteSystemArchitecture () 587015d818bSTodd Fiala { 588015d818bSTodd Fiala if (m_remote_platform_sp) 589015d818bSTodd Fiala return m_remote_platform_sp->GetRemoteSystemArchitecture (); 590015d818bSTodd Fiala return ArchSpec(); 591015d818bSTodd Fiala } 592015d818bSTodd Fiala 593015d818bSTodd Fiala const char * 594015d818bSTodd Fiala PlatformPOSIX::GetHostname () 595015d818bSTodd Fiala { 596015d818bSTodd Fiala if (IsHost()) 597015d818bSTodd Fiala return Platform::GetHostname(); 598015d818bSTodd Fiala 599015d818bSTodd Fiala if (m_remote_platform_sp) 600015d818bSTodd Fiala return m_remote_platform_sp->GetHostname (); 601015d818bSTodd Fiala return NULL; 602015d818bSTodd Fiala } 603015d818bSTodd Fiala 604015d818bSTodd Fiala const char * 605015d818bSTodd Fiala PlatformPOSIX::GetUserName (uint32_t uid) 606015d818bSTodd Fiala { 607015d818bSTodd Fiala // Check the cache in Platform in case we have already looked this uid up 608015d818bSTodd Fiala const char *user_name = Platform::GetUserName(uid); 609015d818bSTodd Fiala if (user_name) 610015d818bSTodd Fiala return user_name; 611015d818bSTodd Fiala 612015d818bSTodd Fiala if (IsRemote() && m_remote_platform_sp) 613015d818bSTodd Fiala return m_remote_platform_sp->GetUserName(uid); 614015d818bSTodd Fiala return NULL; 615015d818bSTodd Fiala } 616015d818bSTodd Fiala 617015d818bSTodd Fiala const char * 618015d818bSTodd Fiala PlatformPOSIX::GetGroupName (uint32_t gid) 619015d818bSTodd Fiala { 620015d818bSTodd Fiala const char *group_name = Platform::GetGroupName(gid); 621015d818bSTodd Fiala if (group_name) 622015d818bSTodd Fiala return group_name; 623015d818bSTodd Fiala 624015d818bSTodd Fiala if (IsRemote() && m_remote_platform_sp) 625015d818bSTodd Fiala return m_remote_platform_sp->GetGroupName(gid); 626015d818bSTodd Fiala return NULL; 627015d818bSTodd Fiala } 628015d818bSTodd Fiala 629015d818bSTodd Fiala Error 630015d818bSTodd Fiala PlatformPOSIX::ConnectRemote (Args& args) 631015d818bSTodd Fiala { 632015d818bSTodd Fiala Error error; 633015d818bSTodd Fiala if (IsHost()) 634015d818bSTodd Fiala { 635015d818bSTodd Fiala error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); 636015d818bSTodd Fiala } 637015d818bSTodd Fiala else 638015d818bSTodd Fiala { 639015d818bSTodd Fiala if (!m_remote_platform_sp) 640615eb7e6SGreg Clayton m_remote_platform_sp = Platform::Create (ConstString("remote-gdb-server"), error); 641015d818bSTodd Fiala 642015d818bSTodd Fiala if (m_remote_platform_sp && error.Success()) 643015d818bSTodd Fiala error = m_remote_platform_sp->ConnectRemote (args); 644015d818bSTodd Fiala else 645015d818bSTodd Fiala error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); 646015d818bSTodd Fiala 647015d818bSTodd Fiala if (error.Fail()) 648015d818bSTodd Fiala m_remote_platform_sp.reset(); 649015d818bSTodd Fiala } 650015d818bSTodd Fiala 651015d818bSTodd Fiala if (error.Success() && m_remote_platform_sp) 652015d818bSTodd Fiala { 653015d818bSTodd Fiala if (m_options.get()) 654015d818bSTodd Fiala { 655015d818bSTodd Fiala OptionGroupOptions* options = m_options.get(); 656015d818bSTodd Fiala OptionGroupPlatformRSync* m_rsync_options = (OptionGroupPlatformRSync*)options->GetGroupWithOption('r'); 657015d818bSTodd Fiala OptionGroupPlatformSSH* m_ssh_options = (OptionGroupPlatformSSH*)options->GetGroupWithOption('s'); 658015d818bSTodd Fiala OptionGroupPlatformCaching* m_cache_options = (OptionGroupPlatformCaching*)options->GetGroupWithOption('c'); 659015d818bSTodd Fiala 660015d818bSTodd Fiala if (m_rsync_options->m_rsync) 661015d818bSTodd Fiala { 662015d818bSTodd Fiala SetSupportsRSync(true); 663015d818bSTodd Fiala SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str()); 664015d818bSTodd Fiala SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str()); 665015d818bSTodd Fiala SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname); 666015d818bSTodd Fiala } 667015d818bSTodd Fiala if (m_ssh_options->m_ssh) 668015d818bSTodd Fiala { 669015d818bSTodd Fiala SetSupportsSSH(true); 670015d818bSTodd Fiala SetSSHOpts(m_ssh_options->m_ssh_opts.c_str()); 671015d818bSTodd Fiala } 672015d818bSTodd Fiala SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str()); 673015d818bSTodd Fiala } 674015d818bSTodd Fiala } 675015d818bSTodd Fiala 676015d818bSTodd Fiala return error; 677015d818bSTodd Fiala } 678015d818bSTodd Fiala 679015d818bSTodd Fiala Error 680015d818bSTodd Fiala PlatformPOSIX::DisconnectRemote () 681015d818bSTodd Fiala { 682015d818bSTodd Fiala Error error; 683015d818bSTodd Fiala 684015d818bSTodd Fiala if (IsHost()) 685015d818bSTodd Fiala { 686015d818bSTodd Fiala error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString()); 687015d818bSTodd Fiala } 688015d818bSTodd Fiala else 689015d818bSTodd Fiala { 690015d818bSTodd Fiala if (m_remote_platform_sp) 691015d818bSTodd Fiala error = m_remote_platform_sp->DisconnectRemote (); 692015d818bSTodd Fiala else 693015d818bSTodd Fiala error.SetErrorString ("the platform is not currently connected"); 694015d818bSTodd Fiala } 695015d818bSTodd Fiala return error; 696015d818bSTodd Fiala } 697015d818bSTodd Fiala 698348fb385STodd Fiala Error 699348fb385STodd Fiala PlatformPOSIX::LaunchProcess (ProcessLaunchInfo &launch_info) 700348fb385STodd Fiala { 701348fb385STodd Fiala Error error; 702348fb385STodd Fiala 703348fb385STodd Fiala if (IsHost()) 704348fb385STodd Fiala { 705348fb385STodd Fiala error = Platform::LaunchProcess (launch_info); 706348fb385STodd Fiala } 707348fb385STodd Fiala else 708348fb385STodd Fiala { 709348fb385STodd Fiala if (m_remote_platform_sp) 710348fb385STodd Fiala error = m_remote_platform_sp->LaunchProcess (launch_info); 711348fb385STodd Fiala else 712348fb385STodd Fiala error.SetErrorString ("the platform is not currently connected"); 713348fb385STodd Fiala } 714348fb385STodd Fiala return error; 715348fb385STodd Fiala } 716348fb385STodd Fiala 717348fb385STodd Fiala lldb::ProcessSP 718348fb385STodd Fiala PlatformPOSIX::Attach (ProcessAttachInfo &attach_info, 719348fb385STodd Fiala Debugger &debugger, 720348fb385STodd Fiala Target *target, 721348fb385STodd Fiala Error &error) 722348fb385STodd Fiala { 723348fb385STodd Fiala lldb::ProcessSP process_sp; 724348fb385STodd Fiala Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 725348fb385STodd Fiala 726348fb385STodd Fiala if (IsHost()) 727348fb385STodd Fiala { 728348fb385STodd Fiala if (target == NULL) 729348fb385STodd Fiala { 730348fb385STodd Fiala TargetSP new_target_sp; 731348fb385STodd Fiala 732348fb385STodd Fiala error = debugger.GetTargetList().CreateTarget (debugger, 733348fb385STodd Fiala NULL, 734348fb385STodd Fiala NULL, 735348fb385STodd Fiala false, 736348fb385STodd Fiala NULL, 737348fb385STodd Fiala new_target_sp); 738348fb385STodd Fiala target = new_target_sp.get(); 739348fb385STodd Fiala if (log) 740348fb385STodd Fiala log->Printf ("PlatformPOSIX::%s created new target", __FUNCTION__); 741348fb385STodd Fiala } 742348fb385STodd Fiala else 743348fb385STodd Fiala { 744348fb385STodd Fiala error.Clear(); 745348fb385STodd Fiala if (log) 746348fb385STodd Fiala log->Printf ("PlatformPOSIX::%s target already existed, setting target", __FUNCTION__); 747348fb385STodd Fiala } 748348fb385STodd Fiala 749348fb385STodd Fiala if (target && error.Success()) 750348fb385STodd Fiala { 751348fb385STodd Fiala debugger.GetTargetList().SetSelectedTarget(target); 752348fb385STodd Fiala if (log) 753348fb385STodd Fiala { 754348fb385STodd Fiala ModuleSP exe_module_sp = target->GetExecutableModule (); 755348fb385STodd Fiala log->Printf ("PlatformPOSIX::%s set selected target to %p %s", __FUNCTION__, 756348fb385STodd Fiala target, 757348fb385STodd Fiala exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str () : "<null>" ); 758348fb385STodd Fiala } 759348fb385STodd Fiala 760348fb385STodd Fiala 7618012cadbSGreg Clayton process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), attach_info.GetProcessPluginName(), NULL); 762348fb385STodd Fiala 763348fb385STodd Fiala if (process_sp) 764348fb385STodd Fiala { 765348fb385STodd Fiala // Set UnixSignals appropriately. 766348fb385STodd Fiala process_sp->SetUnixSignals (Host::GetUnixSignals ()); 767348fb385STodd Fiala 768*926af0cdSOleksiy Vyalov auto listener_sp = attach_info.GetHijackListener(); 769*926af0cdSOleksiy Vyalov if (listener_sp == nullptr) 770*926af0cdSOleksiy Vyalov { 771*926af0cdSOleksiy Vyalov listener_sp.reset(new Listener("lldb.PlatformPOSIX.attach.hijack")); 772348fb385STodd Fiala attach_info.SetHijackListener(listener_sp); 773*926af0cdSOleksiy Vyalov } 774348fb385STodd Fiala process_sp->HijackProcessEvents(listener_sp.get()); 775348fb385STodd Fiala error = process_sp->Attach (attach_info); 776348fb385STodd Fiala } 777348fb385STodd Fiala } 778348fb385STodd Fiala } 779348fb385STodd Fiala else 780348fb385STodd Fiala { 781348fb385STodd Fiala if (m_remote_platform_sp) 7828012cadbSGreg Clayton process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error); 783348fb385STodd Fiala else 784348fb385STodd Fiala error.SetErrorString ("the platform is not currently connected"); 785348fb385STodd Fiala } 786348fb385STodd Fiala return process_sp; 787348fb385STodd Fiala } 788348fb385STodd Fiala 789015d818bSTodd Fiala lldb::ProcessSP 790015d818bSTodd Fiala PlatformPOSIX::DebugProcess (ProcessLaunchInfo &launch_info, 791015d818bSTodd Fiala Debugger &debugger, 792015d818bSTodd Fiala Target *target, // Can be NULL, if NULL create a new target, else use existing one 793015d818bSTodd Fiala Error &error) 794015d818bSTodd Fiala { 795015d818bSTodd Fiala ProcessSP process_sp; 796015d818bSTodd Fiala 797015d818bSTodd Fiala if (IsHost()) 798015d818bSTodd Fiala { 799015d818bSTodd Fiala // We are going to hand this process off to debugserver which will be in charge of setting the exit status. 800015d818bSTodd Fiala // We still need to reap it from lldb but if we let the monitor thread also set the exit status, we set up a 801015d818bSTodd Fiala // race between debugserver & us for who will find out about the debugged process's death. 802015d818bSTodd Fiala launch_info.GetFlags().Set(eLaunchFlagDontSetExitStatus); 8038012cadbSGreg Clayton process_sp = Platform::DebugProcess (launch_info, debugger, target, error); 804015d818bSTodd Fiala } 805015d818bSTodd Fiala else 806015d818bSTodd Fiala { 807015d818bSTodd Fiala if (m_remote_platform_sp) 8088012cadbSGreg Clayton process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, error); 809015d818bSTodd Fiala else 810015d818bSTodd Fiala error.SetErrorString ("the platform is not currently connected"); 811015d818bSTodd Fiala } 812015d818bSTodd Fiala return process_sp; 813015d818bSTodd Fiala 814015d818bSTodd Fiala } 815015d818bSTodd Fiala 8162094dbf4SJason Molenda void 8172094dbf4SJason Molenda PlatformPOSIX::CalculateTrapHandlerSymbolNames () 8182094dbf4SJason Molenda { 8192094dbf4SJason Molenda m_trap_handlers.push_back (ConstString ("_sigtramp")); 8202094dbf4SJason Molenda } 821