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