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" 21e0f8f574SDaniel Malea #include "lldb/Host/FileSpec.h" 22e0f8f574SDaniel Malea #include "lldb/Host/Host.h" 23*015d818bSTodd Fiala #include "lldb/Target/ProcessLaunchInfo.h" 24e0f8f574SDaniel Malea 25e0f8f574SDaniel Malea using namespace lldb; 26e0f8f574SDaniel Malea using namespace lldb_private; 27e0f8f574SDaniel Malea 28e0f8f574SDaniel Malea 29e0f8f574SDaniel Malea //------------------------------------------------------------------ 30e0f8f574SDaniel Malea /// Default Constructor 31e0f8f574SDaniel Malea //------------------------------------------------------------------ 32e0f8f574SDaniel Malea PlatformPOSIX::PlatformPOSIX (bool is_host) : 33e0f8f574SDaniel Malea Platform(is_host), // This is the local host platform 34e0f8f574SDaniel Malea m_remote_platform_sp () 35e0f8f574SDaniel Malea { 36e0f8f574SDaniel Malea } 37e0f8f574SDaniel Malea 38e0f8f574SDaniel Malea //------------------------------------------------------------------ 39e0f8f574SDaniel Malea /// Destructor. 40e0f8f574SDaniel Malea /// 41e0f8f574SDaniel Malea /// The destructor is virtual since this class is designed to be 42e0f8f574SDaniel Malea /// inherited from by the plug-in instance. 43e0f8f574SDaniel Malea //------------------------------------------------------------------ 44e0f8f574SDaniel Malea PlatformPOSIX::~PlatformPOSIX() 45e0f8f574SDaniel Malea { 46e0f8f574SDaniel Malea } 47e0f8f574SDaniel Malea 48e0f8f574SDaniel Malea lldb_private::OptionGroupOptions* 49e0f8f574SDaniel Malea PlatformPOSIX::GetConnectionOptions (lldb_private::CommandInterpreter& interpreter) 50e0f8f574SDaniel Malea { 51e0f8f574SDaniel Malea if (m_options.get() == NULL) 52e0f8f574SDaniel Malea { 53e0f8f574SDaniel Malea m_options.reset(new OptionGroupOptions(interpreter)); 54e0f8f574SDaniel Malea m_options->Append(new OptionGroupPlatformRSync()); 55e0f8f574SDaniel Malea m_options->Append(new OptionGroupPlatformSSH()); 56e0f8f574SDaniel Malea m_options->Append(new OptionGroupPlatformCaching()); 57e0f8f574SDaniel Malea } 58e0f8f574SDaniel Malea return m_options.get(); 59e0f8f574SDaniel Malea } 60e0f8f574SDaniel Malea 61*015d818bSTodd Fiala bool 62*015d818bSTodd Fiala PlatformPOSIX::IsConnected () const 63*015d818bSTodd Fiala { 64*015d818bSTodd Fiala if (IsHost()) 65*015d818bSTodd Fiala return true; 66*015d818bSTodd Fiala else if (m_remote_platform_sp) 67*015d818bSTodd Fiala return m_remote_platform_sp->IsConnected(); 68*015d818bSTodd Fiala return false; 69*015d818bSTodd Fiala } 70*015d818bSTodd Fiala 71e0f8f574SDaniel Malea lldb_private::Error 72e0f8f574SDaniel Malea PlatformPOSIX::RunShellCommand (const char *command, // Shouldn't be NULL 73e0f8f574SDaniel Malea const char *working_dir, // Pass NULL to use the current working directory 74e0f8f574SDaniel Malea int *status_ptr, // Pass NULL if you don't want the process exit status 75e0f8f574SDaniel Malea int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit 76e0f8f574SDaniel Malea std::string *command_output, // Pass NULL if you don't want the command output 77e0f8f574SDaniel Malea uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish 78e0f8f574SDaniel Malea { 79e0f8f574SDaniel Malea if (IsHost()) 80e0f8f574SDaniel Malea return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 81e0f8f574SDaniel Malea else 82e0f8f574SDaniel Malea { 83e0f8f574SDaniel Malea if (m_remote_platform_sp) 84e0f8f574SDaniel Malea return m_remote_platform_sp->RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 85e0f8f574SDaniel Malea else 86e0f8f574SDaniel Malea return Error("unable to run a remote command without a platform"); 87e0f8f574SDaniel Malea } 88e0f8f574SDaniel Malea } 89e0f8f574SDaniel Malea 90fbb76349SGreg Clayton Error 91fbb76349SGreg Clayton PlatformPOSIX::MakeDirectory (const char *path, uint32_t file_permissions) 92e0f8f574SDaniel Malea { 93fbb76349SGreg Clayton if (m_remote_platform_sp) 94fbb76349SGreg Clayton return m_remote_platform_sp->MakeDirectory(path, file_permissions); 95fbb76349SGreg Clayton else 96fbb76349SGreg Clayton return Platform::MakeDirectory(path ,file_permissions); 97e0f8f574SDaniel Malea } 98fbb76349SGreg Clayton 99fbb76349SGreg Clayton Error 100fbb76349SGreg Clayton PlatformPOSIX::GetFilePermissions (const char *path, uint32_t &file_permissions) 101fbb76349SGreg Clayton { 102fbb76349SGreg Clayton if (m_remote_platform_sp) 103fbb76349SGreg Clayton return m_remote_platform_sp->GetFilePermissions(path, file_permissions); 104fbb76349SGreg Clayton else 105fbb76349SGreg Clayton return Platform::GetFilePermissions(path ,file_permissions); 106fbb76349SGreg Clayton } 107fbb76349SGreg Clayton 108fbb76349SGreg Clayton Error 109fbb76349SGreg Clayton PlatformPOSIX::SetFilePermissions (const char *path, uint32_t file_permissions) 110fbb76349SGreg Clayton { 111fbb76349SGreg Clayton if (m_remote_platform_sp) 112fbb76349SGreg Clayton return m_remote_platform_sp->MakeDirectory(path, file_permissions); 113fbb76349SGreg Clayton else 114fbb76349SGreg Clayton return Platform::SetFilePermissions(path ,file_permissions); 115e0f8f574SDaniel Malea } 116e0f8f574SDaniel Malea 117e0f8f574SDaniel Malea lldb::user_id_t 118e0f8f574SDaniel Malea PlatformPOSIX::OpenFile (const FileSpec& file_spec, 119e0f8f574SDaniel Malea uint32_t flags, 120fbb76349SGreg Clayton uint32_t mode, 121e0f8f574SDaniel Malea Error &error) 122e0f8f574SDaniel Malea { 123e0f8f574SDaniel Malea if (IsHost()) 124e0f8f574SDaniel Malea return Host::OpenFile(file_spec, flags, mode, error); 125fbb76349SGreg Clayton else if (m_remote_platform_sp) 126e0f8f574SDaniel Malea return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error); 127fbb76349SGreg Clayton else 128e0f8f574SDaniel Malea return Platform::OpenFile(file_spec, flags, mode, error); 129e0f8f574SDaniel Malea } 130e0f8f574SDaniel Malea 131e0f8f574SDaniel Malea bool 132e0f8f574SDaniel Malea PlatformPOSIX::CloseFile (lldb::user_id_t fd, Error &error) 133e0f8f574SDaniel Malea { 134e0f8f574SDaniel Malea if (IsHost()) 135e0f8f574SDaniel Malea return Host::CloseFile(fd, error); 136fbb76349SGreg Clayton else if (m_remote_platform_sp) 137e0f8f574SDaniel Malea return m_remote_platform_sp->CloseFile(fd, error); 138fbb76349SGreg Clayton else 139e0f8f574SDaniel Malea return Platform::CloseFile(fd, error); 140e0f8f574SDaniel Malea } 141e0f8f574SDaniel Malea 142e0f8f574SDaniel Malea uint64_t 143e0f8f574SDaniel Malea PlatformPOSIX::ReadFile (lldb::user_id_t fd, 144e0f8f574SDaniel Malea uint64_t offset, 145e0f8f574SDaniel Malea void *dst, 146e0f8f574SDaniel Malea uint64_t dst_len, 147e0f8f574SDaniel Malea Error &error) 148e0f8f574SDaniel Malea { 149e0f8f574SDaniel Malea if (IsHost()) 150e0f8f574SDaniel Malea return Host::ReadFile(fd, offset, dst, dst_len, error); 151fbb76349SGreg Clayton else if (m_remote_platform_sp) 152e0f8f574SDaniel Malea return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error); 153fbb76349SGreg Clayton else 154e0f8f574SDaniel Malea return Platform::ReadFile(fd, offset, dst, dst_len, error); 155e0f8f574SDaniel Malea } 156e0f8f574SDaniel Malea 157e0f8f574SDaniel Malea uint64_t 158e0f8f574SDaniel Malea PlatformPOSIX::WriteFile (lldb::user_id_t fd, 159e0f8f574SDaniel Malea uint64_t offset, 160e0f8f574SDaniel Malea const void* src, 161e0f8f574SDaniel Malea uint64_t src_len, 162e0f8f574SDaniel Malea Error &error) 163e0f8f574SDaniel Malea { 164e0f8f574SDaniel Malea if (IsHost()) 165e0f8f574SDaniel Malea return Host::WriteFile(fd, offset, src, src_len, error); 166fbb76349SGreg Clayton else if (m_remote_platform_sp) 167e0f8f574SDaniel Malea return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error); 168fbb76349SGreg Clayton else 169e0f8f574SDaniel Malea return Platform::WriteFile(fd, offset, src, src_len, error); 170e0f8f574SDaniel Malea } 171e0f8f574SDaniel Malea 172e0f8f574SDaniel Malea static uint32_t 173e0f8f574SDaniel Malea chown_file(Platform *platform, 174e0f8f574SDaniel Malea const char* path, 175e0f8f574SDaniel Malea uint32_t uid = UINT32_MAX, 176e0f8f574SDaniel Malea uint32_t gid = UINT32_MAX) 177e0f8f574SDaniel Malea { 178e0f8f574SDaniel Malea if (!platform || !path || *path == 0) 179e0f8f574SDaniel Malea return UINT32_MAX; 180e0f8f574SDaniel Malea 181e0f8f574SDaniel Malea if (uid == UINT32_MAX && gid == UINT32_MAX) 182e0f8f574SDaniel Malea return 0; // pretend I did chown correctly - actually I just didn't care 183e0f8f574SDaniel Malea 184e0f8f574SDaniel Malea StreamString command; 185e0f8f574SDaniel Malea command.PutCString("chown "); 186e0f8f574SDaniel Malea if (uid != UINT32_MAX) 187e0f8f574SDaniel Malea command.Printf("%d",uid); 188e0f8f574SDaniel Malea if (gid != UINT32_MAX) 189e0f8f574SDaniel Malea command.Printf(":%d",gid); 190e0f8f574SDaniel Malea command.Printf("%s",path); 191e0f8f574SDaniel Malea int status; 192e0f8f574SDaniel Malea platform->RunShellCommand(command.GetData(), 193e0f8f574SDaniel Malea NULL, 194e0f8f574SDaniel Malea &status, 195e0f8f574SDaniel Malea NULL, 196e0f8f574SDaniel Malea NULL, 197e0f8f574SDaniel Malea 10); 198e0f8f574SDaniel Malea return status; 199e0f8f574SDaniel Malea } 200e0f8f574SDaniel Malea 201e0f8f574SDaniel Malea lldb_private::Error 202e0f8f574SDaniel Malea PlatformPOSIX::PutFile (const lldb_private::FileSpec& source, 203e0f8f574SDaniel Malea const lldb_private::FileSpec& destination, 204e0f8f574SDaniel Malea uint32_t uid, 205e0f8f574SDaniel Malea uint32_t gid) 206e0f8f574SDaniel Malea { 207fbb76349SGreg Clayton Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 208fbb76349SGreg Clayton 209e0f8f574SDaniel Malea if (IsHost()) 210e0f8f574SDaniel Malea { 211e0f8f574SDaniel Malea if (FileSpec::Equal(source, destination, true)) 212e0f8f574SDaniel Malea return Error(); 213e0f8f574SDaniel Malea // cp src dst 214e0f8f574SDaniel Malea // chown uid:gid dst 215e0f8f574SDaniel Malea std::string src_path (source.GetPath()); 216e0f8f574SDaniel Malea if (src_path.empty()) 217e0f8f574SDaniel Malea return Error("unable to get file path for source"); 218e0f8f574SDaniel Malea std::string dst_path (destination.GetPath()); 219e0f8f574SDaniel Malea if (dst_path.empty()) 220e0f8f574SDaniel Malea return Error("unable to get file path for destination"); 221e0f8f574SDaniel Malea StreamString command; 222e0f8f574SDaniel Malea command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str()); 223e0f8f574SDaniel Malea int status; 224e0f8f574SDaniel Malea RunShellCommand(command.GetData(), 225e0f8f574SDaniel Malea NULL, 226e0f8f574SDaniel Malea &status, 227e0f8f574SDaniel Malea NULL, 228e0f8f574SDaniel Malea NULL, 229e0f8f574SDaniel Malea 10); 230e0f8f574SDaniel Malea if (status != 0) 231e0f8f574SDaniel Malea return Error("unable to perform copy"); 232e0f8f574SDaniel Malea if (uid == UINT32_MAX && gid == UINT32_MAX) 233e0f8f574SDaniel Malea return Error(); 234e0f8f574SDaniel Malea if (chown_file(this,dst_path.c_str(),uid,gid) != 0) 235e0f8f574SDaniel Malea return Error("unable to perform chown"); 236e0f8f574SDaniel Malea return Error(); 237e0f8f574SDaniel Malea } 238fbb76349SGreg Clayton else if (m_remote_platform_sp) 239e0f8f574SDaniel Malea { 240e0f8f574SDaniel Malea if (GetSupportsRSync()) 241e0f8f574SDaniel Malea { 242e0f8f574SDaniel Malea std::string src_path (source.GetPath()); 243e0f8f574SDaniel Malea if (src_path.empty()) 244e0f8f574SDaniel Malea return Error("unable to get file path for source"); 245e0f8f574SDaniel Malea std::string dst_path (destination.GetPath()); 246e0f8f574SDaniel Malea if (dst_path.empty()) 247e0f8f574SDaniel Malea return Error("unable to get file path for destination"); 248e0f8f574SDaniel Malea StreamString command; 249e0f8f574SDaniel Malea if (GetIgnoresRemoteHostname()) 250e0f8f574SDaniel Malea { 251e0f8f574SDaniel Malea if (!GetRSyncPrefix()) 252e0f8f574SDaniel Malea command.Printf("rsync %s %s %s", 253e0f8f574SDaniel Malea GetRSyncOpts(), 254e0f8f574SDaniel Malea src_path.c_str(), 255e0f8f574SDaniel Malea dst_path.c_str()); 256e0f8f574SDaniel Malea else 257e0f8f574SDaniel Malea command.Printf("rsync %s %s %s%s", 258e0f8f574SDaniel Malea GetRSyncOpts(), 259e0f8f574SDaniel Malea src_path.c_str(), 260e0f8f574SDaniel Malea GetRSyncPrefix(), 261e0f8f574SDaniel Malea dst_path.c_str()); 262e0f8f574SDaniel Malea } 263e0f8f574SDaniel Malea else 264e0f8f574SDaniel Malea command.Printf("rsync %s %s %s:%s", 265e0f8f574SDaniel Malea GetRSyncOpts(), 266e0f8f574SDaniel Malea src_path.c_str(), 267e0f8f574SDaniel Malea GetHostname(), 268e0f8f574SDaniel Malea dst_path.c_str()); 269e0f8f574SDaniel Malea if (log) 270e0f8f574SDaniel Malea log->Printf("[PutFile] Running command: %s\n", command.GetData()); 271e0f8f574SDaniel Malea int retcode; 272e0f8f574SDaniel Malea Host::RunShellCommand(command.GetData(), 273e0f8f574SDaniel Malea NULL, 274e0f8f574SDaniel Malea &retcode, 275e0f8f574SDaniel Malea NULL, 276e0f8f574SDaniel Malea NULL, 277e0f8f574SDaniel Malea 60); 278e0f8f574SDaniel Malea if (retcode == 0) 279e0f8f574SDaniel Malea { 280e0f8f574SDaniel Malea // Don't chown a local file for a remote system 281e0f8f574SDaniel Malea // if (chown_file(this,dst_path.c_str(),uid,gid) != 0) 282e0f8f574SDaniel Malea // return Error("unable to perform chown"); 283e0f8f574SDaniel Malea return Error(); 284e0f8f574SDaniel Malea } 285e0f8f574SDaniel Malea // if we are still here rsync has failed - let's try the slow way before giving up 286e0f8f574SDaniel Malea } 287fbb76349SGreg Clayton 288fbb76349SGreg Clayton if (log) 289fbb76349SGreg Clayton log->Printf ("PlatformPOSIX::PutFile(src='%s', dst='%s', uid=%u, gid=%u)", 290fbb76349SGreg Clayton source.GetPath().c_str(), 291fbb76349SGreg Clayton destination.GetPath().c_str(), 292fbb76349SGreg Clayton uid, 293fbb76349SGreg Clayton gid); // REMOVE THIS PRINTF PRIOR TO CHECKIN 294e0f8f574SDaniel Malea // open 295e0f8f574SDaniel Malea // read, write, read, write, ... 296e0f8f574SDaniel Malea // close 297e0f8f574SDaniel Malea // chown uid:gid dst 298e0f8f574SDaniel Malea if (log) 299e0f8f574SDaniel Malea log->Printf("[PutFile] Using block by block transfer....\n"); 300fbb76349SGreg Clayton 301fbb76349SGreg Clayton uint32_t source_open_options = File::eOpenOptionRead; 302fbb76349SGreg Clayton if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink) 303fbb76349SGreg Clayton source_open_options |= File::eOpenoptionDontFollowSymlinks; 304fbb76349SGreg Clayton 305fbb76349SGreg Clayton File source_file(source, source_open_options, lldb::eFilePermissionsUserRW); 306fbb76349SGreg Clayton Error error; 307fbb76349SGreg Clayton uint32_t permissions = source_file.GetPermissions(error); 308fbb76349SGreg Clayton if (permissions == 0) 309fbb76349SGreg Clayton permissions = lldb::eFilePermissionsFileDefault; 310fbb76349SGreg Clayton 311e0f8f574SDaniel Malea if (!source_file.IsValid()) 312e0f8f574SDaniel Malea return Error("unable to open source file"); 313e0f8f574SDaniel Malea lldb::user_id_t dest_file = OpenFile (destination, 314e0f8f574SDaniel Malea File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, 315fbb76349SGreg Clayton permissions, 316e0f8f574SDaniel Malea error); 317e0f8f574SDaniel Malea if (log) 318e0f8f574SDaniel Malea log->Printf ("dest_file = %" PRIu64 "\n", dest_file); 319e0f8f574SDaniel Malea if (error.Fail()) 320e0f8f574SDaniel Malea return error; 321e0f8f574SDaniel Malea if (dest_file == UINT64_MAX) 322e0f8f574SDaniel Malea return Error("unable to open target file"); 323e0f8f574SDaniel Malea lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); 324e0f8f574SDaniel Malea uint64_t offset = 0; 325e0f8f574SDaniel Malea while (error.Success()) 326e0f8f574SDaniel Malea { 327e0f8f574SDaniel Malea size_t bytes_read = buffer_sp->GetByteSize(); 328e0f8f574SDaniel Malea error = source_file.Read(buffer_sp->GetBytes(), bytes_read); 329e0f8f574SDaniel Malea if (bytes_read) 330e0f8f574SDaniel Malea { 331e0f8f574SDaniel Malea WriteFile(dest_file, offset, buffer_sp->GetBytes(), bytes_read, error); 332e0f8f574SDaniel Malea offset += bytes_read; 333e0f8f574SDaniel Malea } 334e0f8f574SDaniel Malea else 335e0f8f574SDaniel Malea break; 336e0f8f574SDaniel Malea } 337e0f8f574SDaniel Malea CloseFile(dest_file, error); 338e0f8f574SDaniel Malea if (uid == UINT32_MAX && gid == UINT32_MAX) 339e0f8f574SDaniel Malea return error; 340e0f8f574SDaniel Malea // This is remopve, don't chown a local file... 341e0f8f574SDaniel Malea // std::string dst_path (destination.GetPath()); 342e0f8f574SDaniel Malea // if (chown_file(this,dst_path.c_str(),uid,gid) != 0) 343e0f8f574SDaniel Malea // return Error("unable to perform chown"); 344e0f8f574SDaniel Malea return error; 345e0f8f574SDaniel Malea } 346e0f8f574SDaniel Malea return Platform::PutFile(source,destination,uid,gid); 347e0f8f574SDaniel Malea } 348e0f8f574SDaniel Malea 349e0f8f574SDaniel Malea lldb::user_id_t 350e0f8f574SDaniel Malea PlatformPOSIX::GetFileSize (const FileSpec& file_spec) 351e0f8f574SDaniel Malea { 352e0f8f574SDaniel Malea if (IsHost()) 353e0f8f574SDaniel Malea return Host::GetFileSize(file_spec); 354fbb76349SGreg Clayton else if (m_remote_platform_sp) 355e0f8f574SDaniel Malea return m_remote_platform_sp->GetFileSize(file_spec); 356fbb76349SGreg Clayton else 357e0f8f574SDaniel Malea return Platform::GetFileSize(file_spec); 358e0f8f574SDaniel Malea } 359e0f8f574SDaniel Malea 360fbb76349SGreg Clayton Error 361fbb76349SGreg Clayton PlatformPOSIX::CreateSymlink(const char *src, const char *dst) 362fbb76349SGreg Clayton { 363fbb76349SGreg Clayton if (IsHost()) 364fbb76349SGreg Clayton return Host::Symlink(src, dst); 365fbb76349SGreg Clayton else if (m_remote_platform_sp) 366fbb76349SGreg Clayton return m_remote_platform_sp->CreateSymlink(src, dst); 367fbb76349SGreg Clayton else 368fbb76349SGreg Clayton return Platform::CreateSymlink(src, dst); 369fbb76349SGreg Clayton } 370fbb76349SGreg Clayton 371e0f8f574SDaniel Malea bool 372e0f8f574SDaniel Malea PlatformPOSIX::GetFileExists (const FileSpec& file_spec) 373e0f8f574SDaniel Malea { 374e0f8f574SDaniel Malea if (IsHost()) 375e0f8f574SDaniel Malea return file_spec.Exists(); 376fbb76349SGreg Clayton else if (m_remote_platform_sp) 377e0f8f574SDaniel Malea return m_remote_platform_sp->GetFileExists(file_spec); 378fbb76349SGreg Clayton else 379e0f8f574SDaniel Malea return Platform::GetFileExists(file_spec); 380e0f8f574SDaniel Malea } 381e0f8f574SDaniel Malea 382fbb76349SGreg Clayton Error 383fbb76349SGreg Clayton PlatformPOSIX::Unlink (const char *path) 384e0f8f574SDaniel Malea { 385e0f8f574SDaniel Malea if (IsHost()) 386fbb76349SGreg Clayton return Host::Unlink (path); 387fbb76349SGreg Clayton else if (m_remote_platform_sp) 388fbb76349SGreg Clayton return m_remote_platform_sp->Unlink(path); 389fbb76349SGreg Clayton else 390fbb76349SGreg Clayton return Platform::Unlink(path); 391e0f8f574SDaniel Malea } 392e0f8f574SDaniel Malea 393e0f8f574SDaniel Malea lldb_private::Error 394e0f8f574SDaniel Malea PlatformPOSIX::GetFile (const lldb_private::FileSpec& source /* remote file path */, 395e0f8f574SDaniel Malea const lldb_private::FileSpec& destination /* local file path */) 396e0f8f574SDaniel Malea { 397fbb76349SGreg Clayton Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 398fbb76349SGreg Clayton 399e0f8f574SDaniel Malea // Check the args, first. 400e0f8f574SDaniel Malea std::string src_path (source.GetPath()); 401e0f8f574SDaniel Malea if (src_path.empty()) 402e0f8f574SDaniel Malea return Error("unable to get file path for source"); 403e0f8f574SDaniel Malea std::string dst_path (destination.GetPath()); 404e0f8f574SDaniel Malea if (dst_path.empty()) 405e0f8f574SDaniel Malea return Error("unable to get file path for destination"); 406e0f8f574SDaniel Malea if (IsHost()) 407e0f8f574SDaniel Malea { 408e0f8f574SDaniel Malea if (FileSpec::Equal(source, destination, true)) 409e0f8f574SDaniel Malea return Error("local scenario->source and destination are the same file path: no operation performed"); 410e0f8f574SDaniel Malea // cp src dst 411e0f8f574SDaniel Malea StreamString cp_command; 412e0f8f574SDaniel Malea cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str()); 413e0f8f574SDaniel Malea int status; 414e0f8f574SDaniel Malea RunShellCommand(cp_command.GetData(), 415e0f8f574SDaniel Malea NULL, 416e0f8f574SDaniel Malea &status, 417e0f8f574SDaniel Malea NULL, 418e0f8f574SDaniel Malea NULL, 419e0f8f574SDaniel Malea 10); 420e0f8f574SDaniel Malea if (status != 0) 421e0f8f574SDaniel Malea return Error("unable to perform copy"); 422e0f8f574SDaniel Malea return Error(); 423e0f8f574SDaniel Malea } 424fbb76349SGreg Clayton else if (m_remote_platform_sp) 425e0f8f574SDaniel Malea { 426e0f8f574SDaniel Malea if (GetSupportsRSync()) 427e0f8f574SDaniel Malea { 428e0f8f574SDaniel Malea StreamString command; 429e0f8f574SDaniel Malea if (GetIgnoresRemoteHostname()) 430e0f8f574SDaniel Malea { 431e0f8f574SDaniel Malea if (!GetRSyncPrefix()) 432e0f8f574SDaniel Malea command.Printf("rsync %s %s %s", 433e0f8f574SDaniel Malea GetRSyncOpts(), 434e0f8f574SDaniel Malea src_path.c_str(), 435e0f8f574SDaniel Malea dst_path.c_str()); 436e0f8f574SDaniel Malea else 437e0f8f574SDaniel Malea command.Printf("rsync %s %s%s %s", 438e0f8f574SDaniel Malea GetRSyncOpts(), 439e0f8f574SDaniel Malea GetRSyncPrefix(), 440e0f8f574SDaniel Malea src_path.c_str(), 441e0f8f574SDaniel Malea dst_path.c_str()); 442e0f8f574SDaniel Malea } 443e0f8f574SDaniel Malea else 444e0f8f574SDaniel Malea command.Printf("rsync %s %s:%s %s", 445e0f8f574SDaniel Malea GetRSyncOpts(), 446e0f8f574SDaniel Malea m_remote_platform_sp->GetHostname(), 447e0f8f574SDaniel Malea src_path.c_str(), 448e0f8f574SDaniel Malea dst_path.c_str()); 449e0f8f574SDaniel Malea if (log) 450e0f8f574SDaniel Malea log->Printf("[GetFile] Running command: %s\n", command.GetData()); 451e0f8f574SDaniel Malea int retcode; 452e0f8f574SDaniel Malea Host::RunShellCommand(command.GetData(), 453e0f8f574SDaniel Malea NULL, 454e0f8f574SDaniel Malea &retcode, 455e0f8f574SDaniel Malea NULL, 456e0f8f574SDaniel Malea NULL, 457e0f8f574SDaniel Malea 60); 458e0f8f574SDaniel Malea if (retcode == 0) 459e0f8f574SDaniel Malea return Error(); 460e0f8f574SDaniel Malea // If we are here, rsync has failed - let's try the slow way before giving up 461e0f8f574SDaniel Malea } 462e0f8f574SDaniel Malea // open src and dst 463e0f8f574SDaniel Malea // read/write, read/write, read/write, ... 464e0f8f574SDaniel Malea // close src 465e0f8f574SDaniel Malea // close dst 466e0f8f574SDaniel Malea if (log) 467e0f8f574SDaniel Malea log->Printf("[GetFile] Using block by block transfer....\n"); 468e0f8f574SDaniel Malea Error error; 469e0f8f574SDaniel Malea user_id_t fd_src = OpenFile (source, 470e0f8f574SDaniel Malea File::eOpenOptionRead, 471fbb76349SGreg Clayton lldb::eFilePermissionsFileDefault, 472e0f8f574SDaniel Malea error); 473e0f8f574SDaniel Malea 474e0f8f574SDaniel Malea if (fd_src == UINT64_MAX) 475e0f8f574SDaniel Malea return Error("unable to open source file"); 476e0f8f574SDaniel Malea 477fbb76349SGreg Clayton uint32_t permissions = 0; 478fbb76349SGreg Clayton error = GetFilePermissions(source.GetPath().c_str(), permissions); 479e0f8f574SDaniel Malea 480e0f8f574SDaniel Malea if (permissions == 0) 481fbb76349SGreg Clayton permissions = lldb::eFilePermissionsFileDefault; 482e0f8f574SDaniel Malea 483e0f8f574SDaniel Malea user_id_t fd_dst = Host::OpenFile(destination, 484e0f8f574SDaniel Malea File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, 485e0f8f574SDaniel Malea permissions, 486e0f8f574SDaniel Malea error); 487e0f8f574SDaniel Malea 488e0f8f574SDaniel Malea if (fd_dst == UINT64_MAX) 489e0f8f574SDaniel Malea { 490e0f8f574SDaniel Malea if (error.Success()) 491e0f8f574SDaniel Malea error.SetErrorString("unable to open destination file"); 492e0f8f574SDaniel Malea } 493e0f8f574SDaniel Malea 494e0f8f574SDaniel Malea if (error.Success()) 495e0f8f574SDaniel Malea { 496e0f8f574SDaniel Malea lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); 497e0f8f574SDaniel Malea uint64_t offset = 0; 498e0f8f574SDaniel Malea error.Clear(); 499e0f8f574SDaniel Malea while (error.Success()) 500e0f8f574SDaniel Malea { 501e0f8f574SDaniel Malea const uint64_t n_read = ReadFile (fd_src, 502e0f8f574SDaniel Malea offset, 503e0f8f574SDaniel Malea buffer_sp->GetBytes(), 504e0f8f574SDaniel Malea buffer_sp->GetByteSize(), 505e0f8f574SDaniel Malea error); 506e0f8f574SDaniel Malea if (error.Fail()) 507e0f8f574SDaniel Malea break; 508e0f8f574SDaniel Malea if (n_read == 0) 509e0f8f574SDaniel Malea break; 510e0f8f574SDaniel Malea if (Host::WriteFile(fd_dst, 511e0f8f574SDaniel Malea offset, 512e0f8f574SDaniel Malea buffer_sp->GetBytes(), 513e0f8f574SDaniel Malea n_read, 514e0f8f574SDaniel Malea error) != n_read) 515e0f8f574SDaniel Malea { 516e0f8f574SDaniel Malea if (!error.Fail()) 517e0f8f574SDaniel Malea error.SetErrorString("unable to write to destination file"); 518e0f8f574SDaniel Malea break; 519e0f8f574SDaniel Malea } 520e0f8f574SDaniel Malea offset += n_read; 521e0f8f574SDaniel Malea } 522e0f8f574SDaniel Malea } 523e0f8f574SDaniel Malea // Ignore the close error of src. 524e0f8f574SDaniel Malea if (fd_src != UINT64_MAX) 525e0f8f574SDaniel Malea CloseFile(fd_src, error); 526e0f8f574SDaniel Malea // And close the dst file descriptot. 527e0f8f574SDaniel Malea if (fd_dst != UINT64_MAX && !Host::CloseFile(fd_dst, error)) 528e0f8f574SDaniel Malea { 529e0f8f574SDaniel Malea if (!error.Fail()) 530e0f8f574SDaniel Malea error.SetErrorString("unable to close destination file"); 531e0f8f574SDaniel Malea 532e0f8f574SDaniel Malea } 533e0f8f574SDaniel Malea return error; 534e0f8f574SDaniel Malea } 535e0f8f574SDaniel Malea return Platform::GetFile(source,destination); 536e0f8f574SDaniel Malea } 537e0f8f574SDaniel Malea 538e0f8f574SDaniel Malea std::string 539e0f8f574SDaniel Malea PlatformPOSIX::GetPlatformSpecificConnectionInformation() 540e0f8f574SDaniel Malea { 541e0f8f574SDaniel Malea StreamString stream; 542e0f8f574SDaniel Malea if (GetSupportsRSync()) 543e0f8f574SDaniel Malea { 544e0f8f574SDaniel Malea stream.PutCString("rsync"); 545e0f8f574SDaniel Malea if ( (GetRSyncOpts() && *GetRSyncOpts()) || 546e0f8f574SDaniel Malea (GetRSyncPrefix() && *GetRSyncPrefix()) || 547e0f8f574SDaniel Malea GetIgnoresRemoteHostname()) 548e0f8f574SDaniel Malea { 549e0f8f574SDaniel Malea stream.Printf(", options: "); 550e0f8f574SDaniel Malea if (GetRSyncOpts() && *GetRSyncOpts()) 551e0f8f574SDaniel Malea stream.Printf("'%s' ",GetRSyncOpts()); 552e0f8f574SDaniel Malea stream.Printf(", prefix: "); 553e0f8f574SDaniel Malea if (GetRSyncPrefix() && *GetRSyncPrefix()) 554e0f8f574SDaniel Malea stream.Printf("'%s' ",GetRSyncPrefix()); 555e0f8f574SDaniel Malea if (GetIgnoresRemoteHostname()) 556e0f8f574SDaniel Malea stream.Printf("ignore remote-hostname "); 557e0f8f574SDaniel Malea } 558e0f8f574SDaniel Malea } 559e0f8f574SDaniel Malea if (GetSupportsSSH()) 560e0f8f574SDaniel Malea { 561e0f8f574SDaniel Malea stream.PutCString("ssh"); 562e0f8f574SDaniel Malea if (GetSSHOpts() && *GetSSHOpts()) 563e0f8f574SDaniel Malea stream.Printf(", options: '%s' ",GetSSHOpts()); 564e0f8f574SDaniel Malea } 565e0f8f574SDaniel Malea if (GetLocalCacheDirectory() && *GetLocalCacheDirectory()) 566e0f8f574SDaniel Malea stream.Printf("cache dir: %s",GetLocalCacheDirectory()); 567e0f8f574SDaniel Malea if (stream.GetSize()) 568e0f8f574SDaniel Malea return stream.GetData(); 569e0f8f574SDaniel Malea else 570e0f8f574SDaniel Malea return ""; 571e0f8f574SDaniel Malea } 572e0f8f574SDaniel Malea 573e0f8f574SDaniel Malea bool 574e0f8f574SDaniel Malea PlatformPOSIX::CalculateMD5 (const FileSpec& file_spec, 575e0f8f574SDaniel Malea uint64_t &low, 576e0f8f574SDaniel Malea uint64_t &high) 577e0f8f574SDaniel Malea { 578e0f8f574SDaniel Malea if (IsHost()) 579e0f8f574SDaniel Malea return Platform::CalculateMD5 (file_spec, low, high); 580e0f8f574SDaniel Malea if (m_remote_platform_sp) 581e0f8f574SDaniel Malea return m_remote_platform_sp->CalculateMD5(file_spec, low, high); 582e0f8f574SDaniel Malea return false; 583e0f8f574SDaniel Malea } 584fbb76349SGreg Clayton 585fbb76349SGreg Clayton lldb_private::ConstString 586fbb76349SGreg Clayton PlatformPOSIX::GetRemoteWorkingDirectory() 587fbb76349SGreg Clayton { 588fbb76349SGreg Clayton if (IsRemote() && m_remote_platform_sp) 589fbb76349SGreg Clayton return m_remote_platform_sp->GetRemoteWorkingDirectory(); 590fbb76349SGreg Clayton else 591fbb76349SGreg Clayton return Platform::GetRemoteWorkingDirectory(); 592fbb76349SGreg Clayton } 593fbb76349SGreg Clayton 594fbb76349SGreg Clayton bool 595fbb76349SGreg Clayton PlatformPOSIX::SetRemoteWorkingDirectory(const lldb_private::ConstString &path) 596fbb76349SGreg Clayton { 597fbb76349SGreg Clayton if (IsRemote() && m_remote_platform_sp) 598fbb76349SGreg Clayton return m_remote_platform_sp->SetRemoteWorkingDirectory(path); 599fbb76349SGreg Clayton else 600fbb76349SGreg Clayton return Platform::SetRemoteWorkingDirectory(path); 601fbb76349SGreg Clayton } 602fbb76349SGreg Clayton 603*015d818bSTodd Fiala bool 604*015d818bSTodd Fiala PlatformPOSIX::GetRemoteOSVersion () 605*015d818bSTodd Fiala { 606*015d818bSTodd Fiala if (m_remote_platform_sp) 607*015d818bSTodd Fiala return m_remote_platform_sp->GetOSVersion (m_major_os_version, 608*015d818bSTodd Fiala m_minor_os_version, 609*015d818bSTodd Fiala m_update_os_version); 610*015d818bSTodd Fiala return false; 611*015d818bSTodd Fiala } 612*015d818bSTodd Fiala 613*015d818bSTodd Fiala bool 614*015d818bSTodd Fiala PlatformPOSIX::GetRemoteOSBuildString (std::string &s) 615*015d818bSTodd Fiala { 616*015d818bSTodd Fiala if (m_remote_platform_sp) 617*015d818bSTodd Fiala return m_remote_platform_sp->GetRemoteOSBuildString (s); 618*015d818bSTodd Fiala s.clear(); 619*015d818bSTodd Fiala return false; 620*015d818bSTodd Fiala } 621*015d818bSTodd Fiala 622*015d818bSTodd Fiala bool 623*015d818bSTodd Fiala PlatformPOSIX::GetRemoteOSKernelDescription (std::string &s) 624*015d818bSTodd Fiala { 625*015d818bSTodd Fiala if (m_remote_platform_sp) 626*015d818bSTodd Fiala return m_remote_platform_sp->GetRemoteOSKernelDescription (s); 627*015d818bSTodd Fiala s.clear(); 628*015d818bSTodd Fiala return false; 629*015d818bSTodd Fiala } 630*015d818bSTodd Fiala 631*015d818bSTodd Fiala // Remote Platform subclasses need to override this function 632*015d818bSTodd Fiala ArchSpec 633*015d818bSTodd Fiala PlatformPOSIX::GetRemoteSystemArchitecture () 634*015d818bSTodd Fiala { 635*015d818bSTodd Fiala if (m_remote_platform_sp) 636*015d818bSTodd Fiala return m_remote_platform_sp->GetRemoteSystemArchitecture (); 637*015d818bSTodd Fiala return ArchSpec(); 638*015d818bSTodd Fiala } 639*015d818bSTodd Fiala 640*015d818bSTodd Fiala const char * 641*015d818bSTodd Fiala PlatformPOSIX::GetHostname () 642*015d818bSTodd Fiala { 643*015d818bSTodd Fiala if (IsHost()) 644*015d818bSTodd Fiala return Platform::GetHostname(); 645*015d818bSTodd Fiala 646*015d818bSTodd Fiala if (m_remote_platform_sp) 647*015d818bSTodd Fiala return m_remote_platform_sp->GetHostname (); 648*015d818bSTodd Fiala return NULL; 649*015d818bSTodd Fiala } 650*015d818bSTodd Fiala 651*015d818bSTodd Fiala const char * 652*015d818bSTodd Fiala PlatformPOSIX::GetUserName (uint32_t uid) 653*015d818bSTodd Fiala { 654*015d818bSTodd Fiala // Check the cache in Platform in case we have already looked this uid up 655*015d818bSTodd Fiala const char *user_name = Platform::GetUserName(uid); 656*015d818bSTodd Fiala if (user_name) 657*015d818bSTodd Fiala return user_name; 658*015d818bSTodd Fiala 659*015d818bSTodd Fiala if (IsRemote() && m_remote_platform_sp) 660*015d818bSTodd Fiala return m_remote_platform_sp->GetUserName(uid); 661*015d818bSTodd Fiala return NULL; 662*015d818bSTodd Fiala } 663*015d818bSTodd Fiala 664*015d818bSTodd Fiala const char * 665*015d818bSTodd Fiala PlatformPOSIX::GetGroupName (uint32_t gid) 666*015d818bSTodd Fiala { 667*015d818bSTodd Fiala const char *group_name = Platform::GetGroupName(gid); 668*015d818bSTodd Fiala if (group_name) 669*015d818bSTodd Fiala return group_name; 670*015d818bSTodd Fiala 671*015d818bSTodd Fiala if (IsRemote() && m_remote_platform_sp) 672*015d818bSTodd Fiala return m_remote_platform_sp->GetGroupName(gid); 673*015d818bSTodd Fiala return NULL; 674*015d818bSTodd Fiala } 675*015d818bSTodd Fiala 676*015d818bSTodd Fiala Error 677*015d818bSTodd Fiala PlatformPOSIX::ConnectRemote (Args& args) 678*015d818bSTodd Fiala { 679*015d818bSTodd Fiala Error error; 680*015d818bSTodd Fiala if (IsHost()) 681*015d818bSTodd Fiala { 682*015d818bSTodd Fiala error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); 683*015d818bSTodd Fiala } 684*015d818bSTodd Fiala else 685*015d818bSTodd Fiala { 686*015d818bSTodd Fiala if (!m_remote_platform_sp) 687*015d818bSTodd Fiala m_remote_platform_sp = Platform::Create ("remote-gdb-server", error); 688*015d818bSTodd Fiala 689*015d818bSTodd Fiala if (m_remote_platform_sp && error.Success()) 690*015d818bSTodd Fiala error = m_remote_platform_sp->ConnectRemote (args); 691*015d818bSTodd Fiala else 692*015d818bSTodd Fiala error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); 693*015d818bSTodd Fiala 694*015d818bSTodd Fiala if (error.Fail()) 695*015d818bSTodd Fiala m_remote_platform_sp.reset(); 696*015d818bSTodd Fiala } 697*015d818bSTodd Fiala 698*015d818bSTodd Fiala if (error.Success() && m_remote_platform_sp) 699*015d818bSTodd Fiala { 700*015d818bSTodd Fiala if (m_options.get()) 701*015d818bSTodd Fiala { 702*015d818bSTodd Fiala OptionGroupOptions* options = m_options.get(); 703*015d818bSTodd Fiala OptionGroupPlatformRSync* m_rsync_options = (OptionGroupPlatformRSync*)options->GetGroupWithOption('r'); 704*015d818bSTodd Fiala OptionGroupPlatformSSH* m_ssh_options = (OptionGroupPlatformSSH*)options->GetGroupWithOption('s'); 705*015d818bSTodd Fiala OptionGroupPlatformCaching* m_cache_options = (OptionGroupPlatformCaching*)options->GetGroupWithOption('c'); 706*015d818bSTodd Fiala 707*015d818bSTodd Fiala if (m_rsync_options->m_rsync) 708*015d818bSTodd Fiala { 709*015d818bSTodd Fiala SetSupportsRSync(true); 710*015d818bSTodd Fiala SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str()); 711*015d818bSTodd Fiala SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str()); 712*015d818bSTodd Fiala SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname); 713*015d818bSTodd Fiala } 714*015d818bSTodd Fiala if (m_ssh_options->m_ssh) 715*015d818bSTodd Fiala { 716*015d818bSTodd Fiala SetSupportsSSH(true); 717*015d818bSTodd Fiala SetSSHOpts(m_ssh_options->m_ssh_opts.c_str()); 718*015d818bSTodd Fiala } 719*015d818bSTodd Fiala SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str()); 720*015d818bSTodd Fiala } 721*015d818bSTodd Fiala } 722*015d818bSTodd Fiala 723*015d818bSTodd Fiala return error; 724*015d818bSTodd Fiala } 725*015d818bSTodd Fiala 726*015d818bSTodd Fiala Error 727*015d818bSTodd Fiala PlatformPOSIX::DisconnectRemote () 728*015d818bSTodd Fiala { 729*015d818bSTodd Fiala Error error; 730*015d818bSTodd Fiala 731*015d818bSTodd Fiala if (IsHost()) 732*015d818bSTodd Fiala { 733*015d818bSTodd Fiala error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString()); 734*015d818bSTodd Fiala } 735*015d818bSTodd Fiala else 736*015d818bSTodd Fiala { 737*015d818bSTodd Fiala if (m_remote_platform_sp) 738*015d818bSTodd Fiala error = m_remote_platform_sp->DisconnectRemote (); 739*015d818bSTodd Fiala else 740*015d818bSTodd Fiala error.SetErrorString ("the platform is not currently connected"); 741*015d818bSTodd Fiala } 742*015d818bSTodd Fiala return error; 743*015d818bSTodd Fiala } 744*015d818bSTodd Fiala 745*015d818bSTodd Fiala lldb::ProcessSP 746*015d818bSTodd Fiala PlatformPOSIX::DebugProcess (ProcessLaunchInfo &launch_info, 747*015d818bSTodd Fiala Debugger &debugger, 748*015d818bSTodd Fiala Target *target, // Can be NULL, if NULL create a new target, else use existing one 749*015d818bSTodd Fiala Listener &listener, 750*015d818bSTodd Fiala Error &error) 751*015d818bSTodd Fiala { 752*015d818bSTodd Fiala ProcessSP process_sp; 753*015d818bSTodd Fiala 754*015d818bSTodd Fiala if (IsHost()) 755*015d818bSTodd Fiala { 756*015d818bSTodd Fiala // We are going to hand this process off to debugserver which will be in charge of setting the exit status. 757*015d818bSTodd 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 758*015d818bSTodd Fiala // race between debugserver & us for who will find out about the debugged process's death. 759*015d818bSTodd Fiala launch_info.GetFlags().Set(eLaunchFlagDontSetExitStatus); 760*015d818bSTodd Fiala process_sp = Platform::DebugProcess (launch_info, debugger, target, listener, error); 761*015d818bSTodd Fiala } 762*015d818bSTodd Fiala else 763*015d818bSTodd Fiala { 764*015d818bSTodd Fiala if (m_remote_platform_sp) 765*015d818bSTodd Fiala process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, listener, error); 766*015d818bSTodd Fiala else 767*015d818bSTodd Fiala error.SetErrorString ("the platform is not currently connected"); 768*015d818bSTodd Fiala } 769*015d818bSTodd Fiala return process_sp; 770*015d818bSTodd Fiala 771*015d818bSTodd Fiala } 772*015d818bSTodd Fiala 7732094dbf4SJason Molenda void 7742094dbf4SJason Molenda PlatformPOSIX::CalculateTrapHandlerSymbolNames () 7752094dbf4SJason Molenda { 7762094dbf4SJason Molenda m_trap_handlers.push_back (ConstString ("_sigtramp")); 7772094dbf4SJason Molenda } 778