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" 18e0f8f574SDaniel Malea #include "lldb/Core/Log.h" 19e0f8f574SDaniel Malea #include "lldb/Core/StreamString.h" 20e0f8f574SDaniel Malea #include "lldb/Host/File.h" 21c00cf4a0SZachary Turner #include "lldb/Host/FileCache.h" 22e0f8f574SDaniel Malea #include "lldb/Host/FileSpec.h" 23c00cf4a0SZachary Turner #include "lldb/Host/FileSystem.h" 24e0f8f574SDaniel Malea #include "lldb/Host/Host.h" 25015d818bSTodd Fiala #include "lldb/Target/ProcessLaunchInfo.h" 26e0f8f574SDaniel Malea 27e0f8f574SDaniel Malea using namespace lldb; 28e0f8f574SDaniel Malea using namespace lldb_private; 29e0f8f574SDaniel Malea 30e0f8f574SDaniel Malea 31e0f8f574SDaniel Malea //------------------------------------------------------------------ 32e0f8f574SDaniel Malea /// Default Constructor 33e0f8f574SDaniel Malea //------------------------------------------------------------------ 34e0f8f574SDaniel Malea PlatformPOSIX::PlatformPOSIX (bool is_host) : 35e0f8f574SDaniel Malea Platform(is_host), // This is the local host platform 36e0f8f574SDaniel Malea m_remote_platform_sp () 37e0f8f574SDaniel Malea { 38e0f8f574SDaniel Malea } 39e0f8f574SDaniel Malea 40e0f8f574SDaniel Malea //------------------------------------------------------------------ 41e0f8f574SDaniel Malea /// Destructor. 42e0f8f574SDaniel Malea /// 43e0f8f574SDaniel Malea /// The destructor is virtual since this class is designed to be 44e0f8f574SDaniel Malea /// inherited from by the plug-in instance. 45e0f8f574SDaniel Malea //------------------------------------------------------------------ 46e0f8f574SDaniel Malea PlatformPOSIX::~PlatformPOSIX() 47e0f8f574SDaniel Malea { 48e0f8f574SDaniel Malea } 49e0f8f574SDaniel Malea 50e0f8f574SDaniel Malea lldb_private::OptionGroupOptions* 51e0f8f574SDaniel Malea PlatformPOSIX::GetConnectionOptions (lldb_private::CommandInterpreter& interpreter) 52e0f8f574SDaniel Malea { 53e0f8f574SDaniel Malea if (m_options.get() == NULL) 54e0f8f574SDaniel Malea { 55e0f8f574SDaniel Malea m_options.reset(new OptionGroupOptions(interpreter)); 56e0f8f574SDaniel Malea m_options->Append(new OptionGroupPlatformRSync()); 57e0f8f574SDaniel Malea m_options->Append(new OptionGroupPlatformSSH()); 58e0f8f574SDaniel Malea m_options->Append(new OptionGroupPlatformCaching()); 59e0f8f574SDaniel Malea } 60e0f8f574SDaniel Malea return m_options.get(); 61e0f8f574SDaniel Malea } 62e0f8f574SDaniel Malea 63015d818bSTodd Fiala bool 64015d818bSTodd Fiala PlatformPOSIX::IsConnected () const 65015d818bSTodd Fiala { 66015d818bSTodd Fiala if (IsHost()) 67015d818bSTodd Fiala return true; 68015d818bSTodd Fiala else if (m_remote_platform_sp) 69015d818bSTodd Fiala return m_remote_platform_sp->IsConnected(); 70015d818bSTodd Fiala return false; 71015d818bSTodd Fiala } 72015d818bSTodd Fiala 73e0f8f574SDaniel Malea lldb_private::Error 74e0f8f574SDaniel Malea PlatformPOSIX::RunShellCommand (const char *command, // Shouldn't be NULL 75e0f8f574SDaniel Malea const char *working_dir, // Pass NULL to use the current working directory 76e0f8f574SDaniel Malea int *status_ptr, // Pass NULL if you don't want the process exit status 77e0f8f574SDaniel Malea int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit 78e0f8f574SDaniel Malea std::string *command_output, // Pass NULL if you don't want the command output 79e0f8f574SDaniel Malea uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish 80e0f8f574SDaniel Malea { 81e0f8f574SDaniel Malea if (IsHost()) 82e0f8f574SDaniel Malea return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 83e0f8f574SDaniel Malea else 84e0f8f574SDaniel Malea { 85e0f8f574SDaniel Malea if (m_remote_platform_sp) 86e0f8f574SDaniel Malea return m_remote_platform_sp->RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 87e0f8f574SDaniel Malea else 88e0f8f574SDaniel Malea return Error("unable to run a remote command without a platform"); 89e0f8f574SDaniel Malea } 90e0f8f574SDaniel Malea } 91e0f8f574SDaniel Malea 92fbb76349SGreg Clayton Error 93fbb76349SGreg Clayton PlatformPOSIX::MakeDirectory (const char *path, uint32_t file_permissions) 94e0f8f574SDaniel Malea { 95fbb76349SGreg Clayton if (m_remote_platform_sp) 96fbb76349SGreg Clayton return m_remote_platform_sp->MakeDirectory(path, file_permissions); 97fbb76349SGreg Clayton else 98fbb76349SGreg Clayton return Platform::MakeDirectory(path ,file_permissions); 99e0f8f574SDaniel Malea } 100fbb76349SGreg Clayton 101fbb76349SGreg Clayton Error 102fbb76349SGreg Clayton PlatformPOSIX::GetFilePermissions (const char *path, uint32_t &file_permissions) 103fbb76349SGreg Clayton { 104fbb76349SGreg Clayton if (m_remote_platform_sp) 105fbb76349SGreg Clayton return m_remote_platform_sp->GetFilePermissions(path, file_permissions); 106fbb76349SGreg Clayton else 107fbb76349SGreg Clayton return Platform::GetFilePermissions(path ,file_permissions); 108fbb76349SGreg Clayton } 109fbb76349SGreg Clayton 110fbb76349SGreg Clayton Error 111fbb76349SGreg Clayton PlatformPOSIX::SetFilePermissions (const char *path, uint32_t file_permissions) 112fbb76349SGreg Clayton { 113fbb76349SGreg Clayton if (m_remote_platform_sp) 1141cfb98abSZachary Turner return m_remote_platform_sp->SetFilePermissions(path, file_permissions); 115fbb76349SGreg Clayton else 116fbb76349SGreg Clayton return Platform::SetFilePermissions(path ,file_permissions); 117e0f8f574SDaniel Malea } 118e0f8f574SDaniel Malea 119e0f8f574SDaniel Malea lldb::user_id_t 120e0f8f574SDaniel Malea PlatformPOSIX::OpenFile (const FileSpec& file_spec, 121e0f8f574SDaniel Malea uint32_t flags, 122fbb76349SGreg Clayton uint32_t mode, 123e0f8f574SDaniel Malea Error &error) 124e0f8f574SDaniel Malea { 125e0f8f574SDaniel Malea if (IsHost()) 126c00cf4a0SZachary Turner return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error); 127fbb76349SGreg Clayton else if (m_remote_platform_sp) 128e0f8f574SDaniel Malea return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error); 129fbb76349SGreg Clayton else 130e0f8f574SDaniel Malea return Platform::OpenFile(file_spec, flags, mode, error); 131e0f8f574SDaniel Malea } 132e0f8f574SDaniel Malea 133e0f8f574SDaniel Malea bool 134e0f8f574SDaniel Malea PlatformPOSIX::CloseFile (lldb::user_id_t fd, Error &error) 135e0f8f574SDaniel Malea { 136e0f8f574SDaniel Malea if (IsHost()) 137c00cf4a0SZachary Turner return FileCache::GetInstance().CloseFile(fd, error); 138fbb76349SGreg Clayton else if (m_remote_platform_sp) 139e0f8f574SDaniel Malea return m_remote_platform_sp->CloseFile(fd, error); 140fbb76349SGreg Clayton else 141e0f8f574SDaniel Malea return Platform::CloseFile(fd, error); 142e0f8f574SDaniel Malea } 143e0f8f574SDaniel Malea 144e0f8f574SDaniel Malea uint64_t 145e0f8f574SDaniel Malea PlatformPOSIX::ReadFile (lldb::user_id_t fd, 146e0f8f574SDaniel Malea uint64_t offset, 147e0f8f574SDaniel Malea void *dst, 148e0f8f574SDaniel Malea uint64_t dst_len, 149e0f8f574SDaniel Malea Error &error) 150e0f8f574SDaniel Malea { 151e0f8f574SDaniel Malea if (IsHost()) 152c00cf4a0SZachary Turner return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error); 153fbb76349SGreg Clayton else if (m_remote_platform_sp) 154e0f8f574SDaniel Malea return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error); 155fbb76349SGreg Clayton else 156e0f8f574SDaniel Malea return Platform::ReadFile(fd, offset, dst, dst_len, error); 157e0f8f574SDaniel Malea } 158e0f8f574SDaniel Malea 159e0f8f574SDaniel Malea uint64_t 160e0f8f574SDaniel Malea PlatformPOSIX::WriteFile (lldb::user_id_t fd, 161e0f8f574SDaniel Malea uint64_t offset, 162e0f8f574SDaniel Malea const void* src, 163e0f8f574SDaniel Malea uint64_t src_len, 164e0f8f574SDaniel Malea Error &error) 165e0f8f574SDaniel Malea { 166e0f8f574SDaniel Malea if (IsHost()) 167c00cf4a0SZachary Turner return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error); 168fbb76349SGreg Clayton else if (m_remote_platform_sp) 169e0f8f574SDaniel Malea return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error); 170fbb76349SGreg Clayton else 171e0f8f574SDaniel Malea return Platform::WriteFile(fd, offset, src, src_len, error); 172e0f8f574SDaniel Malea } 173e0f8f574SDaniel Malea 174e0f8f574SDaniel Malea static uint32_t 175e0f8f574SDaniel Malea chown_file(Platform *platform, 176e0f8f574SDaniel Malea const char* path, 177e0f8f574SDaniel Malea uint32_t uid = UINT32_MAX, 178e0f8f574SDaniel Malea uint32_t gid = UINT32_MAX) 179e0f8f574SDaniel Malea { 180e0f8f574SDaniel Malea if (!platform || !path || *path == 0) 181e0f8f574SDaniel Malea return UINT32_MAX; 182e0f8f574SDaniel Malea 183e0f8f574SDaniel Malea if (uid == UINT32_MAX && gid == UINT32_MAX) 184e0f8f574SDaniel Malea return 0; // pretend I did chown correctly - actually I just didn't care 185e0f8f574SDaniel Malea 186e0f8f574SDaniel Malea StreamString command; 187e0f8f574SDaniel Malea command.PutCString("chown "); 188e0f8f574SDaniel Malea if (uid != UINT32_MAX) 189e0f8f574SDaniel Malea command.Printf("%d",uid); 190e0f8f574SDaniel Malea if (gid != UINT32_MAX) 191e0f8f574SDaniel Malea command.Printf(":%d",gid); 192e0f8f574SDaniel Malea command.Printf("%s",path); 193e0f8f574SDaniel Malea int status; 194e0f8f574SDaniel Malea platform->RunShellCommand(command.GetData(), 195e0f8f574SDaniel Malea NULL, 196e0f8f574SDaniel Malea &status, 197e0f8f574SDaniel Malea NULL, 198e0f8f574SDaniel Malea NULL, 199e0f8f574SDaniel Malea 10); 200e0f8f574SDaniel Malea return status; 201e0f8f574SDaniel Malea } 202e0f8f574SDaniel Malea 203e0f8f574SDaniel Malea lldb_private::Error 204e0f8f574SDaniel Malea PlatformPOSIX::PutFile (const lldb_private::FileSpec& source, 205e0f8f574SDaniel Malea const lldb_private::FileSpec& destination, 206e0f8f574SDaniel Malea uint32_t uid, 207e0f8f574SDaniel Malea uint32_t gid) 208e0f8f574SDaniel Malea { 209fbb76349SGreg Clayton Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 210fbb76349SGreg Clayton 211e0f8f574SDaniel Malea if (IsHost()) 212e0f8f574SDaniel Malea { 213e0f8f574SDaniel Malea if (FileSpec::Equal(source, destination, true)) 214e0f8f574SDaniel Malea return Error(); 215e0f8f574SDaniel Malea // cp src dst 216e0f8f574SDaniel Malea // chown uid:gid dst 217e0f8f574SDaniel Malea std::string src_path (source.GetPath()); 218e0f8f574SDaniel Malea if (src_path.empty()) 219e0f8f574SDaniel Malea return Error("unable to get file path for source"); 220e0f8f574SDaniel Malea std::string dst_path (destination.GetPath()); 221e0f8f574SDaniel Malea if (dst_path.empty()) 222e0f8f574SDaniel Malea return Error("unable to get file path for destination"); 223e0f8f574SDaniel Malea StreamString command; 224e0f8f574SDaniel Malea command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str()); 225e0f8f574SDaniel Malea int status; 226e0f8f574SDaniel Malea RunShellCommand(command.GetData(), 227e0f8f574SDaniel Malea NULL, 228e0f8f574SDaniel Malea &status, 229e0f8f574SDaniel Malea NULL, 230e0f8f574SDaniel Malea NULL, 231e0f8f574SDaniel Malea 10); 232e0f8f574SDaniel Malea if (status != 0) 233e0f8f574SDaniel Malea return Error("unable to perform copy"); 234e0f8f574SDaniel Malea if (uid == UINT32_MAX && gid == UINT32_MAX) 235e0f8f574SDaniel Malea return Error(); 236e0f8f574SDaniel Malea if (chown_file(this,dst_path.c_str(),uid,gid) != 0) 237e0f8f574SDaniel Malea return Error("unable to perform chown"); 238e0f8f574SDaniel Malea return Error(); 239e0f8f574SDaniel Malea } 240fbb76349SGreg Clayton else if (m_remote_platform_sp) 241e0f8f574SDaniel Malea { 242e0f8f574SDaniel Malea if (GetSupportsRSync()) 243e0f8f574SDaniel Malea { 244e0f8f574SDaniel Malea std::string src_path (source.GetPath()); 245e0f8f574SDaniel Malea if (src_path.empty()) 246e0f8f574SDaniel Malea return Error("unable to get file path for source"); 247e0f8f574SDaniel Malea std::string dst_path (destination.GetPath()); 248e0f8f574SDaniel Malea if (dst_path.empty()) 249e0f8f574SDaniel Malea return Error("unable to get file path for destination"); 250e0f8f574SDaniel Malea StreamString command; 251e0f8f574SDaniel Malea if (GetIgnoresRemoteHostname()) 252e0f8f574SDaniel Malea { 253e0f8f574SDaniel Malea if (!GetRSyncPrefix()) 254e0f8f574SDaniel Malea command.Printf("rsync %s %s %s", 255e0f8f574SDaniel Malea GetRSyncOpts(), 256e0f8f574SDaniel Malea src_path.c_str(), 257e0f8f574SDaniel Malea dst_path.c_str()); 258e0f8f574SDaniel Malea else 259e0f8f574SDaniel Malea command.Printf("rsync %s %s %s%s", 260e0f8f574SDaniel Malea GetRSyncOpts(), 261e0f8f574SDaniel Malea src_path.c_str(), 262e0f8f574SDaniel Malea GetRSyncPrefix(), 263e0f8f574SDaniel Malea dst_path.c_str()); 264e0f8f574SDaniel Malea } 265e0f8f574SDaniel Malea else 266e0f8f574SDaniel Malea command.Printf("rsync %s %s %s:%s", 267e0f8f574SDaniel Malea GetRSyncOpts(), 268e0f8f574SDaniel Malea src_path.c_str(), 269e0f8f574SDaniel Malea GetHostname(), 270e0f8f574SDaniel Malea dst_path.c_str()); 271e0f8f574SDaniel Malea if (log) 272e0f8f574SDaniel Malea log->Printf("[PutFile] Running command: %s\n", command.GetData()); 273e0f8f574SDaniel Malea int retcode; 274e0f8f574SDaniel Malea Host::RunShellCommand(command.GetData(), 275e0f8f574SDaniel Malea NULL, 276e0f8f574SDaniel Malea &retcode, 277e0f8f574SDaniel Malea NULL, 278e0f8f574SDaniel Malea NULL, 279e0f8f574SDaniel Malea 60); 280e0f8f574SDaniel Malea if (retcode == 0) 281e0f8f574SDaniel Malea { 282e0f8f574SDaniel Malea // Don't chown a local file for a remote system 283e0f8f574SDaniel Malea // if (chown_file(this,dst_path.c_str(),uid,gid) != 0) 284e0f8f574SDaniel Malea // return Error("unable to perform chown"); 285e0f8f574SDaniel Malea return Error(); 286e0f8f574SDaniel Malea } 287e0f8f574SDaniel Malea // if we are still here rsync has failed - let's try the slow way before giving up 288e0f8f574SDaniel Malea } 289fbb76349SGreg Clayton 290fbb76349SGreg Clayton if (log) 291fbb76349SGreg Clayton log->Printf ("PlatformPOSIX::PutFile(src='%s', dst='%s', uid=%u, gid=%u)", 292fbb76349SGreg Clayton source.GetPath().c_str(), 293fbb76349SGreg Clayton destination.GetPath().c_str(), 294fbb76349SGreg Clayton uid, 295fbb76349SGreg Clayton gid); // REMOVE THIS PRINTF PRIOR TO CHECKIN 296e0f8f574SDaniel Malea // open 297e0f8f574SDaniel Malea // read, write, read, write, ... 298e0f8f574SDaniel Malea // close 299e0f8f574SDaniel Malea // chown uid:gid dst 300e0f8f574SDaniel Malea if (log) 301e0f8f574SDaniel Malea log->Printf("[PutFile] Using block by block transfer....\n"); 302fbb76349SGreg Clayton 303fbb76349SGreg Clayton uint32_t source_open_options = File::eOpenOptionRead; 304fbb76349SGreg Clayton if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink) 305fbb76349SGreg Clayton source_open_options |= File::eOpenoptionDontFollowSymlinks; 306fbb76349SGreg Clayton 307fbb76349SGreg Clayton File source_file(source, source_open_options, lldb::eFilePermissionsUserRW); 308fbb76349SGreg Clayton Error error; 309fbb76349SGreg Clayton uint32_t permissions = source_file.GetPermissions(error); 310fbb76349SGreg Clayton if (permissions == 0) 311fbb76349SGreg Clayton permissions = lldb::eFilePermissionsFileDefault; 312fbb76349SGreg Clayton 313e0f8f574SDaniel Malea if (!source_file.IsValid()) 314e0f8f574SDaniel Malea return Error("unable to open source file"); 315e0f8f574SDaniel Malea lldb::user_id_t dest_file = OpenFile (destination, 316e0f8f574SDaniel Malea File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, 317fbb76349SGreg Clayton permissions, 318e0f8f574SDaniel Malea error); 319e0f8f574SDaniel Malea if (log) 320e0f8f574SDaniel Malea log->Printf ("dest_file = %" PRIu64 "\n", dest_file); 321e0f8f574SDaniel Malea if (error.Fail()) 322e0f8f574SDaniel Malea return error; 323e0f8f574SDaniel Malea if (dest_file == UINT64_MAX) 324e0f8f574SDaniel Malea return Error("unable to open target file"); 325e0f8f574SDaniel Malea lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); 326e0f8f574SDaniel Malea uint64_t offset = 0; 327e0f8f574SDaniel Malea while (error.Success()) 328e0f8f574SDaniel Malea { 329e0f8f574SDaniel Malea size_t bytes_read = buffer_sp->GetByteSize(); 330e0f8f574SDaniel Malea error = source_file.Read(buffer_sp->GetBytes(), bytes_read); 331e0f8f574SDaniel Malea if (bytes_read) 332e0f8f574SDaniel Malea { 33390d9a35fSGreg Clayton const uint64_t bytes_written = WriteFile(dest_file, offset, buffer_sp->GetBytes(), bytes_read, error); 33490d9a35fSGreg Clayton offset += bytes_written; 33590d9a35fSGreg Clayton if (bytes_written != bytes_read) 33690d9a35fSGreg Clayton { 33790d9a35fSGreg Clayton // We didn't write the correct numbe of bytes, so adjust 33890d9a35fSGreg Clayton // the file position in the source file we are reading from... 33990d9a35fSGreg Clayton source_file.SeekFromStart(offset); 34090d9a35fSGreg Clayton } 341e0f8f574SDaniel Malea } 342e0f8f574SDaniel Malea else 343e0f8f574SDaniel Malea break; 344e0f8f574SDaniel Malea } 345e0f8f574SDaniel Malea CloseFile(dest_file, error); 346e0f8f574SDaniel Malea if (uid == UINT32_MAX && gid == UINT32_MAX) 347e0f8f574SDaniel Malea return error; 348e0f8f574SDaniel Malea // This is remopve, don't chown a local file... 349e0f8f574SDaniel Malea // std::string dst_path (destination.GetPath()); 350e0f8f574SDaniel Malea // if (chown_file(this,dst_path.c_str(),uid,gid) != 0) 351e0f8f574SDaniel Malea // return Error("unable to perform chown"); 35290d9a35fSGreg Clayton 35390d9a35fSGreg Clayton 35490d9a35fSGreg Clayton uint64_t src_md5[2]; 35590d9a35fSGreg Clayton uint64_t dst_md5[2]; 35690d9a35fSGreg Clayton 35790d9a35fSGreg Clayton if (FileSystem::CalculateMD5 (source, src_md5[0], src_md5[1]) && CalculateMD5 (destination, dst_md5[0], dst_md5[1])) 35890d9a35fSGreg Clayton { 35990d9a35fSGreg Clayton if (src_md5[0] != dst_md5[0] || src_md5[1] != dst_md5[1]) 36090d9a35fSGreg Clayton { 36190d9a35fSGreg Clayton error.SetErrorString("md5 checksum of installed file doesn't match, installation failed"); 36290d9a35fSGreg Clayton } 36390d9a35fSGreg Clayton } 364e0f8f574SDaniel Malea return error; 365e0f8f574SDaniel Malea } 366e0f8f574SDaniel Malea return Platform::PutFile(source,destination,uid,gid); 367e0f8f574SDaniel Malea } 368e0f8f574SDaniel Malea 369e0f8f574SDaniel Malea lldb::user_id_t 370e0f8f574SDaniel Malea PlatformPOSIX::GetFileSize (const FileSpec& file_spec) 371e0f8f574SDaniel Malea { 372e0f8f574SDaniel Malea if (IsHost()) 373c00cf4a0SZachary Turner return FileSystem::GetFileSize(file_spec); 374fbb76349SGreg Clayton else if (m_remote_platform_sp) 375e0f8f574SDaniel Malea return m_remote_platform_sp->GetFileSize(file_spec); 376fbb76349SGreg Clayton else 377e0f8f574SDaniel Malea return Platform::GetFileSize(file_spec); 378e0f8f574SDaniel Malea } 379e0f8f574SDaniel Malea 380fbb76349SGreg Clayton Error 381fbb76349SGreg Clayton PlatformPOSIX::CreateSymlink(const char *src, const char *dst) 382fbb76349SGreg Clayton { 383fbb76349SGreg Clayton if (IsHost()) 384c00cf4a0SZachary Turner return FileSystem::Symlink(src, dst); 385fbb76349SGreg Clayton else if (m_remote_platform_sp) 386fbb76349SGreg Clayton return m_remote_platform_sp->CreateSymlink(src, dst); 387fbb76349SGreg Clayton else 388fbb76349SGreg Clayton return Platform::CreateSymlink(src, dst); 389fbb76349SGreg Clayton } 390fbb76349SGreg Clayton 391e0f8f574SDaniel Malea bool 392e0f8f574SDaniel Malea PlatformPOSIX::GetFileExists (const FileSpec& file_spec) 393e0f8f574SDaniel Malea { 394e0f8f574SDaniel Malea if (IsHost()) 395e0f8f574SDaniel Malea return file_spec.Exists(); 396fbb76349SGreg Clayton else if (m_remote_platform_sp) 397e0f8f574SDaniel Malea return m_remote_platform_sp->GetFileExists(file_spec); 398fbb76349SGreg Clayton else 399e0f8f574SDaniel Malea return Platform::GetFileExists(file_spec); 400e0f8f574SDaniel Malea } 401e0f8f574SDaniel Malea 402fbb76349SGreg Clayton Error 403fbb76349SGreg Clayton PlatformPOSIX::Unlink (const char *path) 404e0f8f574SDaniel Malea { 405e0f8f574SDaniel Malea if (IsHost()) 406c00cf4a0SZachary Turner return FileSystem::Unlink(path); 407fbb76349SGreg Clayton else if (m_remote_platform_sp) 408fbb76349SGreg Clayton return m_remote_platform_sp->Unlink(path); 409fbb76349SGreg Clayton else 410fbb76349SGreg Clayton return Platform::Unlink(path); 411e0f8f574SDaniel Malea } 412e0f8f574SDaniel Malea 413e0f8f574SDaniel Malea lldb_private::Error 414e0f8f574SDaniel Malea PlatformPOSIX::GetFile (const lldb_private::FileSpec& source /* remote file path */, 415e0f8f574SDaniel Malea const lldb_private::FileSpec& destination /* local file path */) 416e0f8f574SDaniel Malea { 417fbb76349SGreg Clayton Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 418fbb76349SGreg Clayton 419e0f8f574SDaniel Malea // Check the args, first. 420e0f8f574SDaniel Malea std::string src_path (source.GetPath()); 421e0f8f574SDaniel Malea if (src_path.empty()) 422e0f8f574SDaniel Malea return Error("unable to get file path for source"); 423e0f8f574SDaniel Malea std::string dst_path (destination.GetPath()); 424e0f8f574SDaniel Malea if (dst_path.empty()) 425e0f8f574SDaniel Malea return Error("unable to get file path for destination"); 426e0f8f574SDaniel Malea if (IsHost()) 427e0f8f574SDaniel Malea { 428e0f8f574SDaniel Malea if (FileSpec::Equal(source, destination, true)) 429e0f8f574SDaniel Malea return Error("local scenario->source and destination are the same file path: no operation performed"); 430e0f8f574SDaniel Malea // cp src dst 431e0f8f574SDaniel Malea StreamString cp_command; 432e0f8f574SDaniel Malea cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str()); 433e0f8f574SDaniel Malea int status; 434e0f8f574SDaniel Malea RunShellCommand(cp_command.GetData(), 435e0f8f574SDaniel Malea NULL, 436e0f8f574SDaniel Malea &status, 437e0f8f574SDaniel Malea NULL, 438e0f8f574SDaniel Malea NULL, 439e0f8f574SDaniel Malea 10); 440e0f8f574SDaniel Malea if (status != 0) 441e0f8f574SDaniel Malea return Error("unable to perform copy"); 442e0f8f574SDaniel Malea return Error(); 443e0f8f574SDaniel Malea } 444fbb76349SGreg Clayton else if (m_remote_platform_sp) 445e0f8f574SDaniel Malea { 446e0f8f574SDaniel Malea if (GetSupportsRSync()) 447e0f8f574SDaniel Malea { 448e0f8f574SDaniel Malea StreamString command; 449e0f8f574SDaniel Malea if (GetIgnoresRemoteHostname()) 450e0f8f574SDaniel Malea { 451e0f8f574SDaniel Malea if (!GetRSyncPrefix()) 452e0f8f574SDaniel Malea command.Printf("rsync %s %s %s", 453e0f8f574SDaniel Malea GetRSyncOpts(), 454e0f8f574SDaniel Malea src_path.c_str(), 455e0f8f574SDaniel Malea dst_path.c_str()); 456e0f8f574SDaniel Malea else 457e0f8f574SDaniel Malea command.Printf("rsync %s %s%s %s", 458e0f8f574SDaniel Malea GetRSyncOpts(), 459e0f8f574SDaniel Malea GetRSyncPrefix(), 460e0f8f574SDaniel Malea src_path.c_str(), 461e0f8f574SDaniel Malea dst_path.c_str()); 462e0f8f574SDaniel Malea } 463e0f8f574SDaniel Malea else 464e0f8f574SDaniel Malea command.Printf("rsync %s %s:%s %s", 465e0f8f574SDaniel Malea GetRSyncOpts(), 466e0f8f574SDaniel Malea m_remote_platform_sp->GetHostname(), 467e0f8f574SDaniel Malea src_path.c_str(), 468e0f8f574SDaniel Malea dst_path.c_str()); 469e0f8f574SDaniel Malea if (log) 470e0f8f574SDaniel Malea log->Printf("[GetFile] Running command: %s\n", command.GetData()); 471e0f8f574SDaniel Malea int retcode; 472e0f8f574SDaniel Malea Host::RunShellCommand(command.GetData(), 473e0f8f574SDaniel Malea NULL, 474e0f8f574SDaniel Malea &retcode, 475e0f8f574SDaniel Malea NULL, 476e0f8f574SDaniel Malea NULL, 477e0f8f574SDaniel Malea 60); 478e0f8f574SDaniel Malea if (retcode == 0) 479e0f8f574SDaniel Malea return Error(); 480e0f8f574SDaniel Malea // If we are here, rsync has failed - let's try the slow way before giving up 481e0f8f574SDaniel Malea } 482e0f8f574SDaniel Malea // open src and dst 483e0f8f574SDaniel Malea // read/write, read/write, read/write, ... 484e0f8f574SDaniel Malea // close src 485e0f8f574SDaniel Malea // close dst 486e0f8f574SDaniel Malea if (log) 487e0f8f574SDaniel Malea log->Printf("[GetFile] Using block by block transfer....\n"); 488e0f8f574SDaniel Malea Error error; 489e0f8f574SDaniel Malea user_id_t fd_src = OpenFile (source, 490e0f8f574SDaniel Malea File::eOpenOptionRead, 491fbb76349SGreg Clayton lldb::eFilePermissionsFileDefault, 492e0f8f574SDaniel Malea error); 493e0f8f574SDaniel Malea 494e0f8f574SDaniel Malea if (fd_src == UINT64_MAX) 495e0f8f574SDaniel Malea return Error("unable to open source file"); 496e0f8f574SDaniel Malea 497fbb76349SGreg Clayton uint32_t permissions = 0; 498fbb76349SGreg Clayton error = GetFilePermissions(source.GetPath().c_str(), permissions); 499e0f8f574SDaniel Malea 500e0f8f574SDaniel Malea if (permissions == 0) 501fbb76349SGreg Clayton permissions = lldb::eFilePermissionsFileDefault; 502e0f8f574SDaniel Malea 503c00cf4a0SZachary Turner user_id_t fd_dst = FileCache::GetInstance().OpenFile( 504c00cf4a0SZachary Turner destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, permissions, 505e0f8f574SDaniel Malea error); 506e0f8f574SDaniel Malea 507e0f8f574SDaniel Malea if (fd_dst == UINT64_MAX) 508e0f8f574SDaniel Malea { 509e0f8f574SDaniel Malea if (error.Success()) 510e0f8f574SDaniel Malea error.SetErrorString("unable to open destination file"); 511e0f8f574SDaniel Malea } 512e0f8f574SDaniel Malea 513e0f8f574SDaniel Malea if (error.Success()) 514e0f8f574SDaniel Malea { 515e0f8f574SDaniel Malea lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); 516e0f8f574SDaniel Malea uint64_t offset = 0; 517e0f8f574SDaniel Malea error.Clear(); 518e0f8f574SDaniel Malea while (error.Success()) 519e0f8f574SDaniel Malea { 520e0f8f574SDaniel Malea const uint64_t n_read = ReadFile (fd_src, 521e0f8f574SDaniel Malea offset, 522e0f8f574SDaniel Malea buffer_sp->GetBytes(), 523e0f8f574SDaniel Malea buffer_sp->GetByteSize(), 524e0f8f574SDaniel Malea error); 525e0f8f574SDaniel Malea if (error.Fail()) 526e0f8f574SDaniel Malea break; 527e0f8f574SDaniel Malea if (n_read == 0) 528e0f8f574SDaniel Malea break; 529c00cf4a0SZachary Turner if (FileCache::GetInstance().WriteFile(fd_dst, offset, buffer_sp->GetBytes(), n_read, error) != n_read) 530e0f8f574SDaniel Malea { 531e0f8f574SDaniel Malea if (!error.Fail()) 532e0f8f574SDaniel Malea error.SetErrorString("unable to write to destination file"); 533e0f8f574SDaniel Malea break; 534e0f8f574SDaniel Malea } 535e0f8f574SDaniel Malea offset += n_read; 536e0f8f574SDaniel Malea } 537e0f8f574SDaniel Malea } 538e0f8f574SDaniel Malea // Ignore the close error of src. 539e0f8f574SDaniel Malea if (fd_src != UINT64_MAX) 540e0f8f574SDaniel Malea CloseFile(fd_src, error); 541e0f8f574SDaniel Malea // And close the dst file descriptot. 542c00cf4a0SZachary Turner if (fd_dst != UINT64_MAX && !FileCache::GetInstance().CloseFile(fd_dst, error)) 543e0f8f574SDaniel Malea { 544e0f8f574SDaniel Malea if (!error.Fail()) 545e0f8f574SDaniel Malea error.SetErrorString("unable to close destination file"); 546e0f8f574SDaniel Malea 547e0f8f574SDaniel Malea } 548e0f8f574SDaniel Malea return error; 549e0f8f574SDaniel Malea } 550e0f8f574SDaniel Malea return Platform::GetFile(source,destination); 551e0f8f574SDaniel Malea } 552e0f8f574SDaniel Malea 553e0f8f574SDaniel Malea std::string 554e0f8f574SDaniel Malea PlatformPOSIX::GetPlatformSpecificConnectionInformation() 555e0f8f574SDaniel Malea { 556e0f8f574SDaniel Malea StreamString stream; 557e0f8f574SDaniel Malea if (GetSupportsRSync()) 558e0f8f574SDaniel Malea { 559e0f8f574SDaniel Malea stream.PutCString("rsync"); 560e0f8f574SDaniel Malea if ( (GetRSyncOpts() && *GetRSyncOpts()) || 561e0f8f574SDaniel Malea (GetRSyncPrefix() && *GetRSyncPrefix()) || 562e0f8f574SDaniel Malea GetIgnoresRemoteHostname()) 563e0f8f574SDaniel Malea { 564e0f8f574SDaniel Malea stream.Printf(", options: "); 565e0f8f574SDaniel Malea if (GetRSyncOpts() && *GetRSyncOpts()) 566e0f8f574SDaniel Malea stream.Printf("'%s' ",GetRSyncOpts()); 567e0f8f574SDaniel Malea stream.Printf(", prefix: "); 568e0f8f574SDaniel Malea if (GetRSyncPrefix() && *GetRSyncPrefix()) 569e0f8f574SDaniel Malea stream.Printf("'%s' ",GetRSyncPrefix()); 570e0f8f574SDaniel Malea if (GetIgnoresRemoteHostname()) 571e0f8f574SDaniel Malea stream.Printf("ignore remote-hostname "); 572e0f8f574SDaniel Malea } 573e0f8f574SDaniel Malea } 574e0f8f574SDaniel Malea if (GetSupportsSSH()) 575e0f8f574SDaniel Malea { 576e0f8f574SDaniel Malea stream.PutCString("ssh"); 577e0f8f574SDaniel Malea if (GetSSHOpts() && *GetSSHOpts()) 578e0f8f574SDaniel Malea stream.Printf(", options: '%s' ",GetSSHOpts()); 579e0f8f574SDaniel Malea } 580e0f8f574SDaniel Malea if (GetLocalCacheDirectory() && *GetLocalCacheDirectory()) 581e0f8f574SDaniel Malea stream.Printf("cache dir: %s",GetLocalCacheDirectory()); 582e0f8f574SDaniel Malea if (stream.GetSize()) 583e0f8f574SDaniel Malea return stream.GetData(); 584e0f8f574SDaniel Malea else 585e0f8f574SDaniel Malea return ""; 586e0f8f574SDaniel Malea } 587e0f8f574SDaniel Malea 588e0f8f574SDaniel Malea bool 589e0f8f574SDaniel Malea PlatformPOSIX::CalculateMD5 (const FileSpec& file_spec, 590e0f8f574SDaniel Malea uint64_t &low, 591e0f8f574SDaniel Malea uint64_t &high) 592e0f8f574SDaniel Malea { 593e0f8f574SDaniel Malea if (IsHost()) 594e0f8f574SDaniel Malea return Platform::CalculateMD5 (file_spec, low, high); 595e0f8f574SDaniel Malea if (m_remote_platform_sp) 596e0f8f574SDaniel Malea return m_remote_platform_sp->CalculateMD5(file_spec, low, high); 597e0f8f574SDaniel Malea return false; 598e0f8f574SDaniel Malea } 599fbb76349SGreg Clayton 600fbb76349SGreg Clayton lldb_private::ConstString 601fbb76349SGreg Clayton PlatformPOSIX::GetRemoteWorkingDirectory() 602fbb76349SGreg Clayton { 603fbb76349SGreg Clayton if (IsRemote() && m_remote_platform_sp) 604fbb76349SGreg Clayton return m_remote_platform_sp->GetRemoteWorkingDirectory(); 605fbb76349SGreg Clayton else 606fbb76349SGreg Clayton return Platform::GetRemoteWorkingDirectory(); 607fbb76349SGreg Clayton } 608fbb76349SGreg Clayton 609fbb76349SGreg Clayton bool 610fbb76349SGreg Clayton PlatformPOSIX::SetRemoteWorkingDirectory(const lldb_private::ConstString &path) 611fbb76349SGreg Clayton { 612fbb76349SGreg Clayton if (IsRemote() && m_remote_platform_sp) 613fbb76349SGreg Clayton return m_remote_platform_sp->SetRemoteWorkingDirectory(path); 614fbb76349SGreg Clayton else 615fbb76349SGreg Clayton return Platform::SetRemoteWorkingDirectory(path); 616fbb76349SGreg Clayton } 617fbb76349SGreg Clayton 618015d818bSTodd Fiala bool 619015d818bSTodd Fiala PlatformPOSIX::GetRemoteOSVersion () 620015d818bSTodd Fiala { 621015d818bSTodd Fiala if (m_remote_platform_sp) 622015d818bSTodd Fiala return m_remote_platform_sp->GetOSVersion (m_major_os_version, 623015d818bSTodd Fiala m_minor_os_version, 624015d818bSTodd Fiala m_update_os_version); 625015d818bSTodd Fiala return false; 626015d818bSTodd Fiala } 627015d818bSTodd Fiala 628015d818bSTodd Fiala bool 629015d818bSTodd Fiala PlatformPOSIX::GetRemoteOSBuildString (std::string &s) 630015d818bSTodd Fiala { 631015d818bSTodd Fiala if (m_remote_platform_sp) 632015d818bSTodd Fiala return m_remote_platform_sp->GetRemoteOSBuildString (s); 633015d818bSTodd Fiala s.clear(); 634015d818bSTodd Fiala return false; 635015d818bSTodd Fiala } 636015d818bSTodd Fiala 637*e15fcaa2STodd Fiala size_t 638*e15fcaa2STodd Fiala PlatformPOSIX::GetEnvironment (StringList &env) 639*e15fcaa2STodd Fiala { 640*e15fcaa2STodd Fiala if (IsRemote()) 641*e15fcaa2STodd Fiala { 642*e15fcaa2STodd Fiala if (m_remote_platform_sp) 643*e15fcaa2STodd Fiala return m_remote_platform_sp->GetEnvironment(env); 644*e15fcaa2STodd Fiala return 0; 645*e15fcaa2STodd Fiala } 646*e15fcaa2STodd Fiala return Host::GetEnvironment(env); 647*e15fcaa2STodd Fiala } 648*e15fcaa2STodd Fiala 649015d818bSTodd Fiala bool 650015d818bSTodd Fiala PlatformPOSIX::GetRemoteOSKernelDescription (std::string &s) 651015d818bSTodd Fiala { 652015d818bSTodd Fiala if (m_remote_platform_sp) 653015d818bSTodd Fiala return m_remote_platform_sp->GetRemoteOSKernelDescription (s); 654015d818bSTodd Fiala s.clear(); 655015d818bSTodd Fiala return false; 656015d818bSTodd Fiala } 657015d818bSTodd Fiala 658015d818bSTodd Fiala // Remote Platform subclasses need to override this function 659015d818bSTodd Fiala ArchSpec 660015d818bSTodd Fiala PlatformPOSIX::GetRemoteSystemArchitecture () 661015d818bSTodd Fiala { 662015d818bSTodd Fiala if (m_remote_platform_sp) 663015d818bSTodd Fiala return m_remote_platform_sp->GetRemoteSystemArchitecture (); 664015d818bSTodd Fiala return ArchSpec(); 665015d818bSTodd Fiala } 666015d818bSTodd Fiala 667015d818bSTodd Fiala const char * 668015d818bSTodd Fiala PlatformPOSIX::GetHostname () 669015d818bSTodd Fiala { 670015d818bSTodd Fiala if (IsHost()) 671015d818bSTodd Fiala return Platform::GetHostname(); 672015d818bSTodd Fiala 673015d818bSTodd Fiala if (m_remote_platform_sp) 674015d818bSTodd Fiala return m_remote_platform_sp->GetHostname (); 675015d818bSTodd Fiala return NULL; 676015d818bSTodd Fiala } 677015d818bSTodd Fiala 678015d818bSTodd Fiala const char * 679015d818bSTodd Fiala PlatformPOSIX::GetUserName (uint32_t uid) 680015d818bSTodd Fiala { 681015d818bSTodd Fiala // Check the cache in Platform in case we have already looked this uid up 682015d818bSTodd Fiala const char *user_name = Platform::GetUserName(uid); 683015d818bSTodd Fiala if (user_name) 684015d818bSTodd Fiala return user_name; 685015d818bSTodd Fiala 686015d818bSTodd Fiala if (IsRemote() && m_remote_platform_sp) 687015d818bSTodd Fiala return m_remote_platform_sp->GetUserName(uid); 688015d818bSTodd Fiala return NULL; 689015d818bSTodd Fiala } 690015d818bSTodd Fiala 691015d818bSTodd Fiala const char * 692015d818bSTodd Fiala PlatformPOSIX::GetGroupName (uint32_t gid) 693015d818bSTodd Fiala { 694015d818bSTodd Fiala const char *group_name = Platform::GetGroupName(gid); 695015d818bSTodd Fiala if (group_name) 696015d818bSTodd Fiala return group_name; 697015d818bSTodd Fiala 698015d818bSTodd Fiala if (IsRemote() && m_remote_platform_sp) 699015d818bSTodd Fiala return m_remote_platform_sp->GetGroupName(gid); 700015d818bSTodd Fiala return NULL; 701015d818bSTodd Fiala } 702015d818bSTodd Fiala 703015d818bSTodd Fiala Error 704015d818bSTodd Fiala PlatformPOSIX::ConnectRemote (Args& args) 705015d818bSTodd Fiala { 706015d818bSTodd Fiala Error error; 707015d818bSTodd Fiala if (IsHost()) 708015d818bSTodd Fiala { 709015d818bSTodd Fiala error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); 710015d818bSTodd Fiala } 711015d818bSTodd Fiala else 712015d818bSTodd Fiala { 713015d818bSTodd Fiala if (!m_remote_platform_sp) 714615eb7e6SGreg Clayton m_remote_platform_sp = Platform::Create (ConstString("remote-gdb-server"), error); 715015d818bSTodd Fiala 716015d818bSTodd Fiala if (m_remote_platform_sp && error.Success()) 717015d818bSTodd Fiala error = m_remote_platform_sp->ConnectRemote (args); 718015d818bSTodd Fiala else 719015d818bSTodd Fiala error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); 720015d818bSTodd Fiala 721015d818bSTodd Fiala if (error.Fail()) 722015d818bSTodd Fiala m_remote_platform_sp.reset(); 723015d818bSTodd Fiala } 724015d818bSTodd Fiala 725015d818bSTodd Fiala if (error.Success() && m_remote_platform_sp) 726015d818bSTodd Fiala { 727015d818bSTodd Fiala if (m_options.get()) 728015d818bSTodd Fiala { 729015d818bSTodd Fiala OptionGroupOptions* options = m_options.get(); 730015d818bSTodd Fiala OptionGroupPlatformRSync* m_rsync_options = (OptionGroupPlatformRSync*)options->GetGroupWithOption('r'); 731015d818bSTodd Fiala OptionGroupPlatformSSH* m_ssh_options = (OptionGroupPlatformSSH*)options->GetGroupWithOption('s'); 732015d818bSTodd Fiala OptionGroupPlatformCaching* m_cache_options = (OptionGroupPlatformCaching*)options->GetGroupWithOption('c'); 733015d818bSTodd Fiala 734015d818bSTodd Fiala if (m_rsync_options->m_rsync) 735015d818bSTodd Fiala { 736015d818bSTodd Fiala SetSupportsRSync(true); 737015d818bSTodd Fiala SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str()); 738015d818bSTodd Fiala SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str()); 739015d818bSTodd Fiala SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname); 740015d818bSTodd Fiala } 741015d818bSTodd Fiala if (m_ssh_options->m_ssh) 742015d818bSTodd Fiala { 743015d818bSTodd Fiala SetSupportsSSH(true); 744015d818bSTodd Fiala SetSSHOpts(m_ssh_options->m_ssh_opts.c_str()); 745015d818bSTodd Fiala } 746015d818bSTodd Fiala SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str()); 747015d818bSTodd Fiala } 748015d818bSTodd Fiala } 749015d818bSTodd Fiala 750015d818bSTodd Fiala return error; 751015d818bSTodd Fiala } 752015d818bSTodd Fiala 753015d818bSTodd Fiala Error 754015d818bSTodd Fiala PlatformPOSIX::DisconnectRemote () 755015d818bSTodd Fiala { 756015d818bSTodd Fiala Error error; 757015d818bSTodd Fiala 758015d818bSTodd Fiala if (IsHost()) 759015d818bSTodd Fiala { 760015d818bSTodd Fiala error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString()); 761015d818bSTodd Fiala } 762015d818bSTodd Fiala else 763015d818bSTodd Fiala { 764015d818bSTodd Fiala if (m_remote_platform_sp) 765015d818bSTodd Fiala error = m_remote_platform_sp->DisconnectRemote (); 766015d818bSTodd Fiala else 767015d818bSTodd Fiala error.SetErrorString ("the platform is not currently connected"); 768015d818bSTodd Fiala } 769015d818bSTodd Fiala return error; 770015d818bSTodd Fiala } 771015d818bSTodd Fiala 772015d818bSTodd Fiala lldb::ProcessSP 773015d818bSTodd Fiala PlatformPOSIX::DebugProcess (ProcessLaunchInfo &launch_info, 774015d818bSTodd Fiala Debugger &debugger, 775015d818bSTodd Fiala Target *target, // Can be NULL, if NULL create a new target, else use existing one 776015d818bSTodd Fiala Listener &listener, 777015d818bSTodd Fiala Error &error) 778015d818bSTodd Fiala { 779015d818bSTodd Fiala ProcessSP process_sp; 780015d818bSTodd Fiala 781015d818bSTodd Fiala if (IsHost()) 782015d818bSTodd Fiala { 783015d818bSTodd Fiala // We are going to hand this process off to debugserver which will be in charge of setting the exit status. 784015d818bSTodd 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 785015d818bSTodd Fiala // race between debugserver & us for who will find out about the debugged process's death. 786015d818bSTodd Fiala launch_info.GetFlags().Set(eLaunchFlagDontSetExitStatus); 787015d818bSTodd Fiala process_sp = Platform::DebugProcess (launch_info, debugger, target, listener, error); 788015d818bSTodd Fiala } 789015d818bSTodd Fiala else 790015d818bSTodd Fiala { 791015d818bSTodd Fiala if (m_remote_platform_sp) 792015d818bSTodd Fiala process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, listener, error); 793015d818bSTodd Fiala else 794015d818bSTodd Fiala error.SetErrorString ("the platform is not currently connected"); 795015d818bSTodd Fiala } 796015d818bSTodd Fiala return process_sp; 797015d818bSTodd Fiala 798015d818bSTodd Fiala } 799015d818bSTodd Fiala 8002094dbf4SJason Molenda void 8012094dbf4SJason Molenda PlatformPOSIX::CalculateTrapHandlerSymbolNames () 8022094dbf4SJason Molenda { 8032094dbf4SJason Molenda m_trap_handlers.push_back (ConstString ("_sigtramp")); 8042094dbf4SJason Molenda } 805