Error FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst) { Error error; std::wstring wsrc, wdst; if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) || !llvm::ConvertUTF8toWide(dst.GetCString(), wdst)) error.SetErrorString(PATH_CONVERSION_ERROR); else if (!::CreateHardLinkW(wsrc.c_str(), wdst.c_str(), nullptr)) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; }
Error PlatformRemoteGDBServer::CreateSymlink(const FileSpec &src, // The name of the link is in src const FileSpec &dst) // The symlink points to dst { Error error = m_gdb_client.CreateSymlink(src, dst); Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); if (log) log->Printf ("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') error = %u (%s)", src.GetCString(), dst.GetCString(), error.GetError(), error.AsCString()); return error; }
Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) { Status error; std::wstring wsrc; if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc)) { error.SetErrorString(PATH_CONVERSION_ERROR); return error; } HANDLE h = ::CreateFileW(wsrc.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (h == INVALID_HANDLE_VALUE) { error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; } std::vector<wchar_t> buf(PATH_MAX + 1); // Subtract 1 from the path length since this function does not add a null // terminator. DWORD result = ::GetFinalPathNameByHandleW( h, buf.data(), buf.size() - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); std::string path; if (result == 0) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); else if (!llvm::convertWideToUTF8(buf.data(), path)) error.SetErrorString(PATH_CONVERSION_ERROR); else dst.SetFile(path, false); ::CloseHandle(h); return error; }
GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_vFile_Open( StringExtractorGDBRemote &packet) { packet.SetFilePos(::strlen("vFile:open:")); std::string path; packet.GetHexByteStringTerminatedBy(path, ','); if (!path.empty()) { if (packet.GetChar() == ',') { uint32_t flags = File::ConvertOpenOptionsForPOSIXOpen(packet.GetHexMaxU32(false, 0)); if (packet.GetChar() == ',') { mode_t mode = packet.GetHexMaxU32(false, 0600); Error error; const FileSpec path_spec{path, true}; int fd = ::open(path_spec.GetCString(), flags, mode); const int save_errno = fd == -1 ? errno : 0; StreamString response; response.PutChar('F'); response.Printf("%i", fd); if (save_errno) response.Printf(",%i", save_errno); return SendPacketNoLock(response.GetString()); } } } return SendErrorResponse(18); }
Error PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) { Error error = m_gdb_client.Unlink(file_spec); Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); if (log) log->Printf("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)", file_spec.GetCString(), error.GetError(), error.AsCString()); return error; }
Error PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec, uint32_t mode) { Error error = m_gdb_client.MakeDirectory(file_spec, mode); Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); if (log) log->Printf ("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) error = %u (%s)", file_spec.GetCString(), mode, error.GetError(), error.AsCString()); return error; }
Error PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions) { Error error = m_gdb_client.SetFilePermissions(file_spec, file_permissions); Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); if (log) log->Printf ("PlatformRemoteGDBServer::SetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)", file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString()); return error; }
Status FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) { Status error; std::wstring wsrc, wdst; if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) || !llvm::ConvertUTF8toWide(dst.GetCString(), wdst)) error.SetErrorString(PATH_CONVERSION_ERROR); if (error.Fail()) return error; DWORD attrib = ::GetFileAttributesW(wdst.c_str()); if (attrib == INVALID_FILE_ATTRIBUTES) { error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; } bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY); DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; BOOL result = ::CreateSymbolicLinkW(wsrc.c_str(), wdst.c_str(), flag); if (!result) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; }
bool ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd, int flags) { int target_fd = open(file_spec.GetCString(), flags, 0666); if (target_fd == -1) return false; if (dup2(target_fd, fd) == -1) return false; return (close(target_fd) == -1) ? false : true; }
bool PlatformRemoteGDBServer::SetRemoteWorkingDirectory( const FileSpec &working_dir) { if (IsConnected()) { // Clear the working directory it case it doesn't get set correctly. This // will // for use to re-read it Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); if (log) log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')", working_dir.GetCString()); return m_gdb_client.SetWorkingDir(working_dir) == 0; } else return Platform::SetRemoteWorkingDirectory(working_dir); }
Error FileSystem::Unlink(const FileSpec &file_spec) { Error error; std::wstring path; if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), path)) { error.SetErrorString(PATH_CONVERSION_ERROR); return error; } BOOL result = ::DeleteFileW(path.c_str()); if (!result) error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; }
static void DupDescriptor(int error_fd, const FileSpec &file_spec, int fd, int flags) { int target_fd = ::open(file_spec.GetCString(), flags, 0666); if (target_fd == -1) ExitWithError(error_fd, "DupDescriptor-open"); if (target_fd == fd) return; if (::dup2(target_fd, fd) == -1) ExitWithError(error_fd, "DupDescriptor-dup2"); ::close(target_fd); return; }
uint32_t File::GetPermissions(const FileSpec &file_spec, Error &error) { if (file_spec) { struct stat file_stats; if (::stat(file_spec.GetCString(), &file_stats) == -1) error.SetErrorToErrno(); else { error.Clear(); return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); } } else error.SetErrorString ("empty file spec"); return 0; }
int FileSystem::GetHardlinkCount(const FileSpec &file_spec) { std::wstring path; if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), path)) return -1; HANDLE file_handle = ::CreateFileW(path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (file_handle == INVALID_HANDLE_VALUE) return -1; AutoHandle auto_file_handle(file_handle); BY_HANDLE_FILE_INFORMATION file_info; if (::GetFileInformationByHandle(file_handle, &file_info)) return file_info.nNumberOfLinks; return -1; }
Error FileSystem::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions) { Error error; // Beware that Windows's permission model is different from Unix's, and it's // not clear if this API is supposed to check ACLs. To match the caller's // expectations as closely as possible, we'll use Microsoft's _stat, which // attempts to emulate POSIX stat. This should be good enough for basic // checks like FileSpec::Readable. struct _stat file_stats; if (::_stat(file_spec.GetCString(), &file_stats) == 0) { // The owner permission bits in "st_mode" currently match the definitions // for the owner file mode bits. file_permissions = file_stats.st_mode & (_S_IREAD | _S_IWRITE | _S_IEXEC); } else { error.SetErrorToErrno(); } return error; }
GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_qModuleInfo (StringExtractorGDBRemote &packet) { packet.SetFilePos(::strlen ("qModuleInfo:")); std::string module_path; packet.GetHexByteStringTerminatedBy(module_path, ';'); if (module_path.empty()) return SendErrorResponse (1); if (packet.GetChar() != ';') return SendErrorResponse (2); std::string triple; packet.GetHexByteString(triple); ArchSpec arch(triple.c_str()); const FileSpec req_module_path_spec(module_path.c_str(), true); const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch); const ModuleSpec module_spec(module_path_spec, arch); ModuleSpecList module_specs; if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, module_specs)) return SendErrorResponse (3); ModuleSpec matched_module_spec; if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) return SendErrorResponse (4); const auto file_offset = matched_module_spec.GetObjectOffset(); const auto file_size = matched_module_spec.GetObjectSize(); const auto uuid_str = matched_module_spec.GetUUID().GetAsString(""); StreamGDBRemote response; if (uuid_str.empty()) { std::string md5_hash; if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(), file_offset, file_size, md5_hash)) return SendErrorResponse (5); response.PutCString ("md5:"); response.PutCStringAsRawHex8(md5_hash.c_str()); } else{ response.PutCString ("uuid:"); response.PutCStringAsRawHex8(uuid_str.c_str()); } response.PutChar(';'); const auto &module_arch = matched_module_spec.GetArchitecture(); response.PutCString("triple:"); response.PutCStringAsRawHex8( module_arch.GetTriple().getTriple().c_str()); response.PutChar(';'); response.PutCString("file_path:"); response.PutCStringAsRawHex8(module_path_spec.GetCString()); response.PutChar(';'); response.PutCString("file_offset:"); response.PutHex64(file_offset); response.PutChar(';'); response.PutCString("file_size:"); response.PutHex64(file_size); response.PutChar(';'); return SendPacketNoLock(response.GetData(), response.GetSize()); }