Index: lldb/trunk/include/lldb/Host/FileCache.h =================================================================== --- lldb/trunk/include/lldb/Host/FileCache.h +++ lldb/trunk/include/lldb/Host/FileCache.h @@ -0,0 +1,45 @@ +//===-- FileCache.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef liblldb_Host_FileCache_h +#define liblldb_Host_FileCache_h + +#include + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" + +#include "lldb/Core/Error.h" +#include "lldb/Host/FileSpec.h" + +namespace lldb_private +{ +class FileCache +{ + private: + FileCache() {} + + typedef std::map FDToFileMap; + + public: + static FileCache &GetInstance(); + + lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags, uint32_t mode, Error &error); + bool CloseFile(lldb::user_id_t fd, Error &error); + + uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Error &error); + uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Error &error); + + private: + static FileCache *m_instance; + + FDToFileMap m_cache; +}; +} + +#endif Index: lldb/trunk/include/lldb/Host/FileSystem.h =================================================================== --- lldb/trunk/include/lldb/Host/FileSystem.h +++ lldb/trunk/include/lldb/Host/FileSystem.h @@ -0,0 +1,43 @@ +//===-- FileSystem.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Host_FileSystem_h +#define liblldb_Host_FileSystem_h + +#include + +#include "lldb/lldb-types.h" + +#include "lldb/Core/Error.h" +#include "lldb/Host/FileSpec.h" + +namespace lldb_private +{ +class FileSystem +{ + public: + static FileSpec::PathSyntax GetNativePathSyntax(); + + static Error MakeDirectory(const char *path, uint32_t mode); + static Error DeleteDirectory(const char *path, bool recurse); + + static Error GetFilePermissions(const char *path, uint32_t &file_permissions); + static Error SetFilePermissions(const char *path, uint32_t file_permissions); + static lldb::user_id_t GetFileSize(const FileSpec &file_spec); + static bool GetFileExists(const FileSpec &file_spec); + + static Error Symlink(const char *src, const char *dst); + static Error Readlink(const char *path, char *buf, size_t buf_len); + static Error Unlink(const char *path); + + static bool CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high); +}; +} + +#endif Index: lldb/trunk/include/lldb/Host/Host.h =================================================================== --- lldb/trunk/include/lldb/Host/Host.h +++ lldb/trunk/include/lldb/Host/Host.h @@ -365,15 +365,6 @@ SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name, size_t len); //------------------------------------------------------------------ - /// Gets the host environment's native path syntax (Windows / Posix). - /// - /// @return - /// \b One of {FileSpec::ePathSyntaxWindows, FileSpec::ePathSyntaxPosix} - //------------------------------------------------------------------ - static FileSpec::PathSyntax - GetHostPathSyntax(); - - //------------------------------------------------------------------ /// Gets the FileSpec of the user profile directory. On Posix-platforms /// this is ~, and on windows this is generally something like /// C:\Users\Alice. @@ -567,63 +558,6 @@ DynamicLibraryGetSymbol (void *dynamic_library_handle, const char *symbol_name, Error &error); - - static Error - MakeDirectory (const char* path, uint32_t mode); - - static Error - RemoveDirectory (const char* path, bool recurse); - - static Error - GetFilePermissions (const char* path, uint32_t &file_permissions); - - static Error - SetFilePermissions (const char* path, uint32_t file_permissions); - - static Error - Symlink (const char *src, const char *dst); - - static Error - Readlink (const char *path, char *buf, size_t buf_len); - - static Error - Unlink (const char *path); - - static lldb::user_id_t - OpenFile (const FileSpec& file_spec, - uint32_t flags, - uint32_t mode, - Error &error); - - static bool - CloseFile (lldb::user_id_t fd, - Error &error); - - static uint64_t - WriteFile (lldb::user_id_t fd, - uint64_t offset, - const void* src, - uint64_t src_len, - Error &error); - - static uint64_t - ReadFile (lldb::user_id_t fd, - uint64_t offset, - void* dst, - uint64_t dst_len, - Error &error); - - static lldb::user_id_t - GetFileSize (const FileSpec& file_spec); - - static bool - GetFileExists (const FileSpec& file_spec); - - static bool - CalculateMD5 (const FileSpec& file_spec, - uint64_t &low, - uint64_t &high); - }; } // namespace lldb_private Index: lldb/trunk/include/lldb/Target/FileAction.h =================================================================== --- lldb/trunk/include/lldb/Target/FileAction.h +++ lldb/trunk/include/lldb/Target/FileAction.h @@ -36,11 +36,23 @@ bool Open(int fd, const char *path, bool read, bool write); - int GetFD() const { return m_fd; } + int + GetFD() const + { + return m_fd; + } - Action GetAction() const { return m_action; } + Action + GetAction() const + { + return m_action; + } - int GetActionArgument() const { return m_arg; } + int + GetActionArgument() const + { + return m_arg; + } const char *GetPath() const; Index: lldb/trunk/lldb.xcodeproj/project.pbxproj =================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj +++ lldb/trunk/lldb.xcodeproj/project.pbxproj @@ -583,6 +583,8 @@ 26FFC19D14FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26FFC19714FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp */; }; 26FFC19E14FC072100087D58 /* DynamicLoaderPOSIXDYLD.h in Headers */ = {isa = PBXBuildFile; fileRef = 26FFC19814FC072100087D58 /* DynamicLoaderPOSIXDYLD.h */; }; 3FDFDDBD199C3A06009756A7 /* FileAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FDFDDBC199C3A06009756A7 /* FileAction.cpp */; }; + 3FDFDDBF199D345E009756A7 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FDFDDBE199D345E009756A7 /* FileCache.cpp */; }; + 3FDFDDC6199D37ED009756A7 /* FileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FDFDDC5199D37ED009756A7 /* FileSystem.cpp */; }; 449ACC98197DEA0B008D175E /* FastDemangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 449ACC96197DE9EC008D175E /* FastDemangle.cpp */; }; 490A36C0180F0E6F00BA31F8 /* PlatformWindows.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 490A36BD180F0E6F00BA31F8 /* PlatformWindows.cpp */; }; 490A36C2180F0E9300BA31F8 /* PlatformWindows.h in Headers */ = {isa = PBXBuildFile; fileRef = 490A36BE180F0E6F00BA31F8 /* PlatformWindows.h */; }; @@ -1734,6 +1736,10 @@ 26FFC19814FC072100087D58 /* DynamicLoaderPOSIXDYLD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLoaderPOSIXDYLD.h; sourceTree = ""; }; 3FDFD6C3199C396E009756A7 /* FileAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileAction.h; path = include/lldb/Target/FileAction.h; sourceTree = ""; }; 3FDFDDBC199C3A06009756A7 /* FileAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileAction.cpp; path = source/Target/FileAction.cpp; sourceTree = ""; }; + 3FDFDDBE199D345E009756A7 /* FileCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileCache.cpp; path = source/Host/common/FileCache.cpp; sourceTree = ""; }; + 3FDFDDC0199D34E2009756A7 /* FileCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FileCache.h; path = include/lldb/Host/FileCache.h; sourceTree = ""; }; + 3FDFDDC1199D34E2009756A7 /* FileSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FileSystem.h; path = include/lldb/Host/FileSystem.h; sourceTree = ""; }; + 3FDFDDC5199D37ED009756A7 /* FileSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileSystem.cpp; path = source/Host/posix/FileSystem.cpp; sourceTree = ""; }; 449ACC96197DE9EC008D175E /* FastDemangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FastDemangle.cpp; path = source/Core/FastDemangle.cpp; sourceTree = ""; }; 4906FD4012F2255300A2A77C /* ASTDumper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTDumper.cpp; path = source/Expression/ASTDumper.cpp; sourceTree = ""; }; 4906FD4412F2257600A2A77C /* ASTDumper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTDumper.h; path = include/lldb/Expression/ASTDumper.h; sourceTree = ""; }; @@ -3440,13 +3446,17 @@ 69A01E1A1236C5D400C660B5 /* common */, 233B009C19610D130090E598 /* linux */, 26BC7EE510F1B88100F91463 /* MacOSX */, + 3FDFDDC4199D37BE009756A7 /* posix */, 26BC7DD210F1B7D500F91463 /* Condition.h */, 266F5CBB12FC846200DFCE33 /* Config.h */, 9456F2231616645A00656F91 /* DynamicLibrary.h */, 26CFDCA01861638D000E63E5 /* Editline.h */, 26BC7DD310F1B7D500F91463 /* Endian.h */, 260C6EA013011578005E16B0 /* File.h */, + 3FDFDDC0199D34E2009756A7 /* FileCache.h */, + 3FDFDDBE199D345E009756A7 /* FileCache.cpp */, 26FA4315130103F400E71120 /* FileSpec.h */, + 3FDFDDC1199D34E2009756A7 /* FileSystem.h */, 26BC7DD410F1B7D500F91463 /* Host.h */, 236124A61986B50E004EFC37 /* IoObject.h */, 26BC7DD510F1B7D500F91463 /* Mutex.h */, @@ -3894,6 +3904,14 @@ path = "POSIX-DYLD"; sourceTree = ""; }; + 3FDFDDC4199D37BE009756A7 /* posix */ = { + isa = PBXGroup; + children = ( + 3FDFDDC5199D37ED009756A7 /* FileSystem.cpp */, + ); + name = posix; + sourceTree = ""; + }; 490A36BA180F0E6F00BA31F8 /* Windows */ = { isa = PBXGroup; children = ( @@ -4748,6 +4766,7 @@ 2689003913353E0400698AC0 /* Debugger.cpp in Sources */, 2689003A13353E0400698AC0 /* Disassembler.cpp in Sources */, 236124A51986B4E2004EFC37 /* Socket.cpp in Sources */, + 3FDFDDBF199D345E009756A7 /* FileCache.cpp in Sources */, AF1729D7182C907200E0AB97 /* HistoryUnwind.cpp in Sources */, 2689003B13353E0400698AC0 /* EmulateInstruction.cpp in Sources */, 2689003C13353E0400698AC0 /* Error.cpp in Sources */, @@ -4971,6 +4990,7 @@ 26BC17AB18C7F4CB00D2196D /* ProcessElfCore.cpp in Sources */, AF1F7B07189C904B0087DB9C /* AppleGetPendingItemsHandler.cpp in Sources */, 26B1FCC21338115F002886E2 /* Host.mm in Sources */, + 3FDFDDC6199D37ED009756A7 /* FileSystem.cpp in Sources */, 26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */, 26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */, 264A97BF133918BC0017F0BE /* PlatformRemoteGDBServer.cpp in Sources */, Index: lldb/trunk/source/CMakeLists.txt =================================================================== --- lldb/trunk/source/CMakeLists.txt +++ lldb/trunk/source/CMakeLists.txt @@ -103,6 +103,10 @@ lldbPluginJITLoaderGDB Ws2_32 ) +else () + list(APPEND LLDB_USED_LIBS + lldbHostPosix + ) endif () # Linux-only libraries Index: lldb/trunk/source/Host/CMakeLists.txt =================================================================== --- lldb/trunk/source/Host/CMakeLists.txt +++ lldb/trunk/source/Host/CMakeLists.txt @@ -1,11 +1,15 @@ add_subdirectory(common) -if (CMAKE_SYSTEM_NAME MATCHES "Darwin") - add_subdirectory(macosx) -elseif (CMAKE_SYSTEM_NAME MATCHES "Linux") - add_subdirectory(linux) -elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - add_subdirectory(freebsd) -elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") +if (CMAKE_SYSTEM_NAME MATCHES "Windows") add_subdirectory(windows) +else() + add_subdirectory(posix) + + if (CMAKE_SYSTEM_NAME MATCHES "Darwin") + add_subdirectory(macosx) + elseif (CMAKE_SYSTEM_NAME MATCHES "Linux") + add_subdirectory(linux) + elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + add_subdirectory(freebsd) + endif() endif() Index: lldb/trunk/source/Host/common/CMakeLists.txt =================================================================== --- lldb/trunk/source/Host/common/CMakeLists.txt +++ lldb/trunk/source/Host/common/CMakeLists.txt @@ -5,6 +5,7 @@ DynamicLibrary.cpp Editline.cpp File.cpp + FileCache.cpp FileSpec.cpp Host.cpp IOObject.cpp Index: lldb/trunk/source/Host/common/FileCache.cpp =================================================================== --- lldb/trunk/source/Host/common/FileCache.cpp +++ lldb/trunk/source/Host/common/FileCache.cpp @@ -0,0 +1,127 @@ +//===-- FileCache.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/FileCache.h" + +#include "lldb/Host/File.h" + +using namespace lldb; +using namespace lldb_private; + +FileCache *FileCache::m_instance = nullptr; + +FileCache & +FileCache::GetInstance() +{ + if (m_instance == nullptr) + m_instance = new FileCache(); + + return *m_instance; +} + +lldb::user_id_t +FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags, uint32_t mode, Error &error) +{ + std::string path(file_spec.GetPath()); + if (path.empty()) + { + error.SetErrorString("empty path"); + return UINT64_MAX; + } + FileSP file_sp(new File()); + error = file_sp->Open(path.c_str(), flags, mode); + if (file_sp->IsValid() == false) + return UINT64_MAX; + lldb::user_id_t fd = file_sp->GetDescriptor(); + m_cache[fd] = file_sp; + return fd; +} + +bool +FileCache::CloseFile(lldb::user_id_t fd, Error &error) +{ + if (fd == UINT64_MAX) + { + error.SetErrorString("invalid file descriptor"); + return false; + } + FDToFileMap::iterator pos = m_cache.find(fd); + if (pos == m_cache.end()) + { + error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); + return false; + } + FileSP file_sp = pos->second; + if (!file_sp) + { + error.SetErrorString("invalid host backing file"); + return false; + } + error = file_sp->Close(); + m_cache.erase(pos); + return error.Success(); +} + +uint64_t +FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Error &error) +{ + if (fd == UINT64_MAX) + { + error.SetErrorString("invalid file descriptor"); + return UINT64_MAX; + } + FDToFileMap::iterator pos = m_cache.find(fd); + if (pos == m_cache.end()) + { + error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); + return false; + } + FileSP file_sp = pos->second; + if (!file_sp) + { + error.SetErrorString("invalid host backing file"); + return UINT64_MAX; + } + if (static_cast(file_sp->SeekFromStart(offset, &error)) != offset || error.Fail()) + return UINT64_MAX; + size_t bytes_written = src_len; + error = file_sp->Write(src, bytes_written); + if (error.Fail()) + return UINT64_MAX; + return bytes_written; +} + +uint64_t +FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Error &error) +{ + if (fd == UINT64_MAX) + { + error.SetErrorString("invalid file descriptor"); + return UINT64_MAX; + } + FDToFileMap::iterator pos = m_cache.find(fd); + if (pos == m_cache.end()) + { + error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); + return false; + } + FileSP file_sp = pos->second; + if (!file_sp) + { + error.SetErrorString("invalid host backing file"); + return UINT64_MAX; + } + if (static_cast(file_sp->SeekFromStart(offset, &error)) != offset || error.Fail()) + return UINT64_MAX; + size_t bytes_read = dst_len; + error = file_sp->Read(dst, bytes_read); + if (error.Fail()) + return UINT64_MAX; + return bytes_read; +} Index: lldb/trunk/source/Host/common/FileSpec.cpp =================================================================== --- lldb/trunk/source/Host/common/FileSpec.cpp +++ lldb/trunk/source/Host/common/FileSpec.cpp @@ -27,22 +27,22 @@ #include #endif -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Program.h" - -#include "lldb/Core/StreamString.h" -#include "lldb/Host/File.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Host/Host.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataBufferMemoryMap.h" #include "lldb/Core/RegularExpression.h" +#include "lldb/Core/StreamString.h" #include "lldb/Core/Stream.h" +#include "lldb/Host/File.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Utility/CleanUp.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" + using namespace lldb; using namespace lldb_private; @@ -166,10 +166,10 @@ llvm::sys::fs::make_absolute(path); } -FileSpec::FileSpec() : - m_directory(), - m_filename(), - m_syntax(Host::GetHostPathSyntax()) +FileSpec::FileSpec() + : m_directory() + , m_filename() + , m_syntax(FileSystem::GetNativePathSyntax()) { } @@ -233,7 +233,8 @@ void FileSpec::Normalize(llvm::SmallVectorImpl &path, PathSyntax syntax) { - if (syntax == ePathSyntaxPosix || (syntax == ePathSyntaxHostNative && Host::GetHostPathSyntax() == ePathSyntaxPosix)) + if (syntax == ePathSyntaxPosix || + (syntax == ePathSyntaxHostNative && FileSystem::GetNativePathSyntax() == ePathSyntaxPosix)) return; std::replace(path.begin(), path.end(), '\\', '/'); @@ -241,7 +242,8 @@ void FileSpec::DeNormalize(llvm::SmallVectorImpl &path, PathSyntax syntax) { - if (syntax == ePathSyntaxPosix || (syntax == ePathSyntaxHostNative && Host::GetHostPathSyntax() == ePathSyntaxPosix)) + if (syntax == ePathSyntaxPosix || + (syntax == ePathSyntaxHostNative && FileSystem::GetNativePathSyntax() == ePathSyntaxPosix)) return; std::replace(path.begin(), path.end(), '/', '\\'); @@ -258,7 +260,7 @@ m_filename.Clear(); m_directory.Clear(); m_is_resolved = false; - m_syntax = (syntax == ePathSyntaxHostNative) ? Host::GetHostPathSyntax() : syntax; + m_syntax = (syntax == ePathSyntaxHostNative) ? FileSystem::GetNativePathSyntax() : syntax; if (pathname == NULL || pathname[0] == '\0') return; @@ -587,7 +589,7 @@ { uint32_t file_permissions = 0; if (*this) - Host::GetFilePermissions(GetPath().c_str(), file_permissions); + FileSystem::GetFilePermissions(GetPath().c_str(), file_permissions); return file_permissions; } Index: lldb/trunk/source/Host/common/Host.cpp =================================================================== --- lldb/trunk/source/Host/common/Host.cpp +++ lldb/trunk/source/Host/common/Host.cpp @@ -67,6 +67,7 @@ #include "lldb/Host/Config.h" #include "lldb/Host/Endian.h" #include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Mutex.h" #include "lldb/Target/FileAction.h" #include "lldb/Target/Process.h" @@ -841,16 +842,6 @@ #endif -FileSpec::PathSyntax -Host::GetHostPathSyntax() -{ -#if defined(_WIN32) - return FileSpec::ePathSyntaxWindows; -#else - return FileSpec::ePathSyntaxPosix; -#endif -} - FileSpec Host::GetUserProfileFileSpec () { @@ -1080,7 +1071,7 @@ // Remove the LLDB temporary directory if we have one. Set "recurse" to // true to all files that were created for the LLDB process can be cleaned up. const bool recurse = true; - Host::RemoveDirectory(tmpdir_file_spec.GetDirectory().GetCString(), recurse); + FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), recurse); } } @@ -1384,10 +1375,12 @@ { StreamString pid_tmpdir; pid_tmpdir.Printf("%s/lldb", tmpdir_cstr); - if (Host::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) + if (FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault) + .Success()) { pid_tmpdir.Printf("/%" PRIu64, Host::GetCurrentProcessID()); - if (Host::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) + if (FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault) + .Success()) { // Make an atexit handler to clean up the process specify LLDB temp dir // and all of its contents. @@ -1960,10 +1953,7 @@ const FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i); if (launch_file_action) { - if (!AddPosixSpawnFileAction (&file_actions, - launch_file_action, - log, - error)) + if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, error)) return error; } } @@ -2033,7 +2023,8 @@ return error; } -bool Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error) +bool +Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error) { if (info == NULL) return false; @@ -2042,57 +2033,59 @@ switch (info->GetAction()) { - case FileAction::eFileActionNone: - error.Clear(); - break; + case FileAction::eFileActionNone: + error.Clear(); + break; - case FileAction::eFileActionClose: - if (info->GetFD() == -1) - error.SetErrorString("invalid fd for posix_spawn_file_actions_addclose(...)"); - else - { - error.SetError(::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), eErrorTypePOSIX); - if (log && (error.Fail() || log)) - error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)", - static_cast(file_actions), info->GetFD()); - } - break; + case FileAction::eFileActionClose: + if (info->GetFD() == -1) + error.SetErrorString("invalid fd for posix_spawn_file_actions_addclose(...)"); + else + { + error.SetError(::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), eErrorTypePOSIX); + if (log && (error.Fail() || log)) + error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)", + static_cast(file_actions), info->GetFD()); + } + break; - case FileAction::eFileActionDuplicate: - if (info->GetFD() == -1) - error.SetErrorString("invalid fd for posix_spawn_file_actions_adddup2(...)"); - else if (info->GetActionArgument() == -1) - error.SetErrorString("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)"); - else - { - error.SetError(::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), info->GetActionArgument()), - eErrorTypePOSIX); - if (log && (error.Fail() || log)) - error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)", - static_cast(file_actions), info->GetFD(), info->GetActionArgument()); - } - break; + case FileAction::eFileActionDuplicate: + if (info->GetFD() == -1) + error.SetErrorString("invalid fd for posix_spawn_file_actions_adddup2(...)"); + else if (info->GetActionArgument() == -1) + error.SetErrorString("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)"); + else + { + error.SetError( + ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), info->GetActionArgument()), + eErrorTypePOSIX); + if (log && (error.Fail() || log)) + error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)", + static_cast(file_actions), info->GetFD(), info->GetActionArgument()); + } + break; - case FileAction::eFileActionOpen: - if (info->GetFD() == -1) - error.SetErrorString("invalid fd in posix_spawn_file_actions_addopen(...)"); - else - { - int oflag = info->GetActionArgument(); + case FileAction::eFileActionOpen: + if (info->GetFD() == -1) + error.SetErrorString("invalid fd in posix_spawn_file_actions_addopen(...)"); + else + { + int oflag = info->GetActionArgument(); - mode_t mode = 0; + mode_t mode = 0; - if (oflag & O_CREAT) - mode = 0640; + if (oflag & O_CREAT) + mode = 0640; - error.SetError( - ::posix_spawn_file_actions_addopen(file_actions, info->GetFD(), info->GetPath(), oflag, mode), - eErrorTypePOSIX); - if (error.Fail() || log) - error.PutToLog(log, "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)", - static_cast(file_actions), info->GetFD(), info->GetPath(), oflag, mode); - } - break; + error.SetError( + ::posix_spawn_file_actions_addopen(file_actions, info->GetFD(), info->GetPath(), oflag, mode), + eErrorTypePOSIX); + if (error.Fail() || log) + error.PutToLog(log, + "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)", + static_cast(file_actions), info->GetFD(), info->GetPath(), oflag, mode); + } + break; } return error.Success(); } @@ -2266,298 +2259,3 @@ } #endif - - -#if !defined(_WIN32) -Error -Host::MakeDirectory (const char* path, uint32_t file_permissions) -{ - Error error; - if (path && path[0]) - { - if (::mkdir(path, file_permissions) != 0) - { - error.SetErrorToErrno(); - switch (error.GetError()) - { - case ENOENT: - { - // Parent directory doesn't exist, so lets make it if we can - FileSpec spec(path, false); - if (spec.GetDirectory() && spec.GetFilename()) - { - // Make the parent directory and try again - Error error2 = Host::MakeDirectory(spec.GetDirectory().GetCString(), file_permissions); - if (error2.Success()) - { - // Try and make the directory again now that the parent directory was made successfully - if (::mkdir(path, file_permissions) == 0) - error.Clear(); - else - error.SetErrorToErrno(); - } - } - } - break; - case EEXIST: - { - FileSpec path_spec(path, false); - if (path_spec.IsDirectory()) - error.Clear(); // It is a directory and it already exists - } - break; - } - } - } - else - { - error.SetErrorString("empty path"); - } - return error; -} - -Error -Host::RemoveDirectory (const char* path, bool recurse) -{ - Error error; - if (path && path[0]) - { - if (recurse) - { - StreamString command; - command.Printf("rm -rf \"%s\"", path); - int status = ::system(command.GetString().c_str()); - if (status != 0) - error.SetError(status, eErrorTypeGeneric); - } - else - { - if (::rmdir(path) != 0) - error.SetErrorToErrno(); - } - } - else - { - error.SetErrorString("empty path"); - } - return error; -} - -Error -Host::GetFilePermissions (const char* path, uint32_t &file_permissions) -{ - Error error; - struct stat file_stats; - if (::stat (path, &file_stats) == 0) - { - // The bits in "st_mode" currently match the definitions - // for the file mode bits in unix. - file_permissions = file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); - } - else - { - error.SetErrorToErrno(); - } - return error; -} - -Error -Host::SetFilePermissions (const char* path, uint32_t file_permissions) -{ - Error error; - if (::chmod(path, file_permissions) != 0) - error.SetErrorToErrno(); - return error; -} - -Error -Host::Symlink (const char *src, const char *dst) -{ - Error error; - if (::symlink(dst, src) == -1) - error.SetErrorToErrno(); - return error; -} - -Error -Host::Unlink (const char *path) -{ - Error error; - if (::unlink(path) == -1) - error.SetErrorToErrno(); - return error; -} - -Error -Host::Readlink (const char *path, char *buf, size_t buf_len) -{ - Error error; - ssize_t count = ::readlink(path, buf, buf_len); - if (count < 0) - error.SetErrorToErrno(); - else if (static_cast(count) < (buf_len-1)) - buf[count] = '\0'; // Success - else - error.SetErrorString("'buf' buffer is too small to contain link contents"); - return error; -} - - -#endif - -typedef std::map FDToFileMap; -FDToFileMap& GetFDToFileMap() -{ - static FDToFileMap g_fd2filemap; - return g_fd2filemap; -} - -lldb::user_id_t -Host::OpenFile (const FileSpec& file_spec, - uint32_t flags, - uint32_t mode, - Error &error) -{ - std::string path (file_spec.GetPath()); - if (path.empty()) - { - error.SetErrorString("empty path"); - return UINT64_MAX; - } - FileSP file_sp(new File()); - error = file_sp->Open(path.c_str(),flags,mode); - if (file_sp->IsValid() == false) - return UINT64_MAX; - lldb::user_id_t fd = file_sp->GetDescriptor(); - GetFDToFileMap()[fd] = file_sp; - return fd; -} - -bool -Host::CloseFile (lldb::user_id_t fd, Error &error) -{ - if (fd == UINT64_MAX) - { - error.SetErrorString ("invalid file descriptor"); - return false; - } - FDToFileMap& file_map = GetFDToFileMap(); - FDToFileMap::iterator pos = file_map.find(fd); - if (pos == file_map.end()) - { - error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd); - return false; - } - FileSP file_sp = pos->second; - if (!file_sp) - { - error.SetErrorString ("invalid host backing file"); - return false; - } - error = file_sp->Close(); - file_map.erase(pos); - return error.Success(); -} - -uint64_t -Host::WriteFile (lldb::user_id_t fd, uint64_t offset, const void* src, uint64_t src_len, Error &error) -{ - if (fd == UINT64_MAX) - { - error.SetErrorString ("invalid file descriptor"); - return UINT64_MAX; - } - FDToFileMap& file_map = GetFDToFileMap(); - FDToFileMap::iterator pos = file_map.find(fd); - if (pos == file_map.end()) - { - error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64 , fd); - return false; - } - FileSP file_sp = pos->second; - if (!file_sp) - { - error.SetErrorString ("invalid host backing file"); - return UINT64_MAX; - } - if (static_cast(file_sp->SeekFromStart(offset, &error)) != offset || - error.Fail()) - return UINT64_MAX; - size_t bytes_written = src_len; - error = file_sp->Write(src, bytes_written); - if (error.Fail()) - return UINT64_MAX; - return bytes_written; -} - -uint64_t -Host::ReadFile (lldb::user_id_t fd, uint64_t offset, void* dst, uint64_t dst_len, Error &error) -{ - if (fd == UINT64_MAX) - { - error.SetErrorString ("invalid file descriptor"); - return UINT64_MAX; - } - FDToFileMap& file_map = GetFDToFileMap(); - FDToFileMap::iterator pos = file_map.find(fd); - if (pos == file_map.end()) - { - error.SetErrorStringWithFormat ("invalid host file descriptor %" PRIu64, fd); - return false; - } - FileSP file_sp = pos->second; - if (!file_sp) - { - error.SetErrorString ("invalid host backing file"); - return UINT64_MAX; - } - if (static_cast(file_sp->SeekFromStart(offset, &error)) != offset || - error.Fail()) - return UINT64_MAX; - size_t bytes_read = dst_len; - error = file_sp->Read(dst ,bytes_read); - if (error.Fail()) - return UINT64_MAX; - return bytes_read; -} - -lldb::user_id_t -Host::GetFileSize (const FileSpec& file_spec) -{ - return file_spec.GetByteSize(); -} - -bool -Host::GetFileExists (const FileSpec& file_spec) -{ - return file_spec.Exists(); -} - -bool -Host::CalculateMD5 (const FileSpec& file_spec, - uint64_t &low, - uint64_t &high) -{ -#if defined (__APPLE__) - StreamString md5_cmd_line; - md5_cmd_line.Printf("md5 -q '%s'", file_spec.GetPath().c_str()); - std::string hash_string; - Error err = Host::RunShellCommand(md5_cmd_line.GetData(), NULL, NULL, NULL, &hash_string, 60); - if (err.Fail()) - return false; - // a correctly formed MD5 is 16-bytes, that is 32 hex digits - // if the output is any other length it is probably wrong - if (hash_string.size() != 32) - return false; - std::string part1(hash_string,0,16); - std::string part2(hash_string,16); - const char* part1_cstr = part1.c_str(); - const char* part2_cstr = part2.c_str(); - high = ::strtoull(part1_cstr, NULL, 16); - low = ::strtoull(part2_cstr, NULL, 16); - return true; -#else - // your own MD5 implementation here - return false; -#endif -} Index: lldb/trunk/source/Host/common/Socket.cpp =================================================================== --- lldb/trunk/source/Host/common/Socket.cpp +++ lldb/trunk/source/Host/common/Socket.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Host/Config.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/SocketAddress.h" #include "lldb/Host/TimeValue.h" @@ -442,7 +443,7 @@ saddr_un.sun_len = SUN_LEN (&saddr_un); #endif - Host::Unlink (name.data()); + FileSystem::Unlink(name.data()); bool success = false; if (::bind (listen_fd, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0) { Index: lldb/trunk/source/Host/posix/CMakeLists.txt =================================================================== --- lldb/trunk/source/Host/posix/CMakeLists.txt +++ lldb/trunk/source/Host/posix/CMakeLists.txt @@ -0,0 +1,5 @@ +set(LLVM_NO_RTTI 1) + +add_lldb_library(lldbHostPosix + FileSystem.cpp + ) Index: lldb/trunk/source/Host/posix/FileSystem.cpp =================================================================== --- lldb/trunk/source/Host/posix/FileSystem.cpp +++ lldb/trunk/source/Host/posix/FileSystem.cpp @@ -0,0 +1,201 @@ +//===-- FileSystem.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/FileSystem.h" + +// C includes +#include +#include + +// lldb Includes +#include "lldb/Core/Error.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/Host.h" + +using namespace lldb; +using namespace lldb_private; + +FileSpec::PathSyntax +FileSystem::GetNativePathSyntax() +{ + return FileSpec::ePathSyntaxPosix; +} + +Error +FileSystem::MakeDirectory(const char *path, uint32_t file_permissions) +{ + Error error; + if (path && path[0]) + { + if (::mkdir(path, file_permissions) != 0) + { + error.SetErrorToErrno(); + switch (error.GetError()) + { + case ENOENT: + { + // Parent directory doesn't exist, so lets make it if we can + FileSpec spec(path, false); + if (spec.GetDirectory() && spec.GetFilename()) + { + // Make the parent directory and try again + Error error2 = MakeDirectory(spec.GetDirectory().GetCString(), file_permissions); + if (error2.Success()) + { + // Try and make the directory again now that the parent directory was made successfully + if (::mkdir(path, file_permissions) == 0) + error.Clear(); + else + error.SetErrorToErrno(); + } + } + } + break; + + case EEXIST: + { + FileSpec path_spec(path, false); + if (path_spec.IsDirectory()) + error.Clear(); // It is a directory and it already exists + } + break; + } + } + } + else + { + error.SetErrorString("empty path"); + } + return error; +} + +Error +FileSystem::DeleteDirectory(const char *path, bool recurse) +{ + Error error; + if (path && path[0]) + { + if (recurse) + { + StreamString command; + command.Printf("rm -rf \"%s\"", path); + int status = ::system(command.GetString().c_str()); + if (status != 0) + error.SetError(status, eErrorTypeGeneric); + } + else + { + if (::rmdir(path) != 0) + error.SetErrorToErrno(); + } + } + else + { + error.SetErrorString("empty path"); + } + return error; +} + +Error +FileSystem::GetFilePermissions(const char *path, uint32_t &file_permissions) +{ + Error error; + struct stat file_stats; + if (::stat(path, &file_stats) == 0) + { + // The bits in "st_mode" currently match the definitions + // for the file mode bits in unix. + file_permissions = file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); + } + else + { + error.SetErrorToErrno(); + } + return error; +} + +Error +FileSystem::SetFilePermissions(const char *path, uint32_t file_permissions) +{ + Error error; + if (::chmod(path, file_permissions) != 0) + error.SetErrorToErrno(); + return error; +} + +lldb::user_id_t +FileSystem::GetFileSize(const FileSpec &file_spec) +{ + return file_spec.GetByteSize(); +} + +bool +FileSystem::GetFileExists(const FileSpec &file_spec) +{ + return file_spec.Exists(); +} + +Error +FileSystem::Symlink(const char *src, const char *dst) +{ + Error error; + if (::symlink(dst, src) == -1) + error.SetErrorToErrno(); + return error; +} + +Error +FileSystem::Unlink(const char *path) +{ + Error error; + if (::unlink(path) == -1) + error.SetErrorToErrno(); + return error; +} + +Error +FileSystem::Readlink(const char *path, char *buf, size_t buf_len) +{ + Error error; + ssize_t count = ::readlink(path, buf, buf_len); + if (count < 0) + error.SetErrorToErrno(); + else if (static_cast(count) < (buf_len - 1)) + buf[count] = '\0'; // Success + else + error.SetErrorString("'buf' buffer is too small to contain link contents"); + return error; +} + +bool +FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high) +{ +#if defined(__APPLE__) + StreamString md5_cmd_line; + md5_cmd_line.Printf("md5 -q '%s'", file_spec.GetPath().c_str()); + std::string hash_string; + Error err = Host::RunShellCommand(md5_cmd_line.GetData(), NULL, NULL, NULL, &hash_string, 60); + if (err.Fail()) + return false; + // a correctly formed MD5 is 16-bytes, that is 32 hex digits + // if the output is any other length it is probably wrong + if (hash_string.size() != 32) + return false; + std::string part1(hash_string, 0, 16); + std::string part2(hash_string, 16); + const char *part1_cstr = part1.c_str(); + const char *part2_cstr = part2.c_str(); + high = ::strtoull(part1_cstr, NULL, 16); + low = ::strtoull(part2_cstr, NULL, 16); + return true; +#else + // your own MD5 implementation here + return false; +#endif +} Index: lldb/trunk/source/Host/windows/CMakeLists.txt =================================================================== --- lldb/trunk/source/Host/windows/CMakeLists.txt +++ lldb/trunk/source/Host/windows/CMakeLists.txt @@ -1,6 +1,7 @@ set(LLVM_NO_RTTI 1) add_lldb_library(lldbHostWindows + FileSystem.cpp Host.cpp ProcessRunLock.cpp Mutex.cpp Index: lldb/trunk/source/Host/windows/FileSystem.cpp =================================================================== --- lldb/trunk/source/Host/windows/FileSystem.cpp +++ lldb/trunk/source/Host/windows/FileSystem.cpp @@ -0,0 +1,146 @@ +//===-- FileSystem.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/windows/windows.h" + +#include + +#include "lldb/Host/FileSystem.h" + +using namespace lldb_private; + +FileSpec::PathSyntax +FileSystem::GetNativePathSyntax() +{ + return FileSpec::ePathSyntaxWindows; +} + +Error +FileSystem::MakeDirectory(const char *path, uint32_t file_permissions) +{ + // On Win32, the mode parameter is ignored, as Windows files and directories support a + // different permission model than POSIX. + Error error; + if (!::CreateDirectory(path, NULL)) + error.SetError(::GetLastError(), lldb::eErrorTypeWin32); + return error; +} + +Error +FileSystem::DeleteDirectory(const char *path, bool recurse) +{ + Error error; + if (!recurse) + { + BOOL result = ::RemoveDirectory(path); + if (!result) + error.SetError(::GetLastError(), lldb::eErrorTypeWin32); + } + else + { + // SHFileOperation() accepts a list of paths, and so must be double-null-terminated to + // indicate the end of the list. + std::string path_buffer(path); + path_buffer.push_back(0); + + SHFILEOPSTRUCT shfos = {0}; + shfos.wFunc = FO_DELETE; + shfos.pFrom = path_buffer.c_str(); + shfos.fFlags = FOF_NO_UI; + + int result = ::SHFileOperation(&shfos); + // TODO(zturner): Correctly handle the intricacies of SHFileOperation return values. + if (result != 0) + error.SetErrorStringWithFormat("SHFileOperation failed"); + } + return error; +} + +Error +FileSystem::GetFilePermissions(const char *path, uint32_t &file_permissions) +{ + Error error; + error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); + return error; +} + +Error +FileSystem::SetFilePermissions(const char *path, uint32_t file_permissions) +{ + Error error; + error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); + return error; +} + +lldb::user_id_t +FileSystem::GetFileSize(const FileSpec &file_spec) +{ + return file_spec.GetByteSize(); +} + +bool +FileSystem::GetFileExists(const FileSpec &file_spec) +{ + return file_spec.Exists(); +} + +Error +FileSystem::Symlink(const char *linkname, const char *target) +{ + Error error; + DWORD attrib = ::GetFileAttributes(target); + 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 = ::CreateSymbolicLink(linkname, target, flag); + if (!result) + error.SetError(::GetLastError(), lldb::eErrorTypeWin32); + return error; +} + +Error +FileSystem::Unlink(const char *path) +{ + Error error; + BOOL result = ::DeleteFile(path); + if (!result) + error.SetError(::GetLastError(), lldb::eErrorTypeWin32); + return error; +} + +Error +FileSystem::Readlink(const char *path, char *buf, size_t buf_len) +{ + Error error; + HANDLE h = ::CreateFile(path, 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; + } + + // Subtract 1 from the path length since this function does not add a null terminator. + DWORD result = ::GetFinalPathNameByHandle(h, buf, buf_len - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); + if (result == 0) + error.SetError(::GetLastError(), lldb::eErrorTypeWin32); + + ::CloseHandle(h); + return error; +} + +bool +FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high) +{ + return false; +} Index: lldb/trunk/source/Host/windows/Host.cpp =================================================================== --- lldb/trunk/source/Host/windows/Host.cpp +++ lldb/trunk/source/Host/windows/Host.cpp @@ -25,7 +25,6 @@ #include "lldb/Core/StreamFile.h" // Windows includes -#include #include using namespace lldb; @@ -124,115 +123,6 @@ } Error -Host::MakeDirectory (const char* path, uint32_t mode) -{ - // On Win32, the mode parameter is ignored, as Windows files and directories support a - // different permission model than POSIX. - Error error; - if (!::CreateDirectory(path, NULL)) - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); - return error; -} - -Error -Host::GetFilePermissions (const char* path, uint32_t &file_permissions) -{ - Error error; - file_permissions = 0; - DWORD attrib = ::GetFileAttributes(path); - if (attrib == INVALID_FILE_ATTRIBUTES) - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); - return error; -} - -Error -Host::SetFilePermissions (const char* path, uint32_t file_permissions) -{ - Error error; - error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); - return error; -} - -Error -Host::Symlink (const char *linkname, const char *target) -{ - Error error; - DWORD attrib = ::GetFileAttributes(target); - 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 = ::CreateSymbolicLink(linkname, target, flag); - if (!result) - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); - return error; -} - -Error -Host::Readlink (const char *path, char *buf, size_t buf_len) -{ - Error error; - HANDLE h = ::CreateFile(path, 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; - } - - // Subtract 1 from the path length since this function does not add a null terminator. - DWORD result = ::GetFinalPathNameByHandle(h, buf, buf_len-1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); - if (result == 0) - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); - - ::CloseHandle(h); - return error; -} - -Error -Host::Unlink (const char *path) -{ - Error error; - BOOL result = ::DeleteFile(path); - if (!result) - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); - return error; -} - -Error -Host::RemoveDirectory (const char* path, bool recurse) -{ - Error error; - if (!recurse) - { - BOOL result = ::RemoveDirectory(path); - if (!result) - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); - } - else - { - // SHFileOperation() accepts a list of paths, and so must be double-null-terminated to - // indicate the end of the list. - std::string path_buffer(path); - path_buffer.push_back(0); - - SHFILEOPSTRUCT shfos = {0}; - shfos.wFunc = FO_DELETE; - shfos.pFrom = path_buffer.c_str(); - shfos.fFlags = FOF_NO_UI; - - int result = ::SHFileOperation(&shfos); - // TODO(zturner): Correctly handle the intricacies of SHFileOperation return values. - if (result != 0) - error.SetErrorStringWithFormat("SHFileOperation failed"); - } - return error; -} - - -Error Host::LaunchProcess (ProcessLaunchInfo &launch_info) { Error error; Index: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -23,6 +23,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/Timer.h" #include "lldb/Host/Host.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Symbols.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" @@ -287,7 +288,7 @@ MakeCacheFolderForFile (const FileSpec& module_cache_spec) { FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent(); - return Host::MakeDirectory(module_cache_folder.GetPath().c_str(), eFilePermissionsDirectoryDefault); + return FileSystem::MakeDirectory(module_cache_folder.GetPath().c_str(), eFilePermissionsDirectoryDefault); } static lldb_private::Error @@ -366,7 +367,7 @@ // when going over the *slow* GDB remote transfer mechanism we first check // the hashes of the files - and only do the actual transfer if they differ uint64_t high_local,high_remote,low_local,low_remote; - Host::CalculateMD5 (module_cache_spec, low_local, high_local); + FileSystem::CalculateMD5(module_cache_spec, low_local, high_local); m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(), low_remote, high_remote); if (low_local != low_remote || high_local != high_remote) { Index: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp +++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp @@ -25,6 +25,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamString.h" #include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Process.h" @@ -284,7 +285,8 @@ // bring in the remote module file FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent(); // try to make the local directory first - Error err = Host::MakeDirectory(module_cache_folder.GetPath().c_str(), eFilePermissionsDirectoryDefault); + Error err = + FileSystem::MakeDirectory(module_cache_folder.GetPath().c_str(), eFilePermissionsDirectoryDefault); if (err.Fail()) return err; err = GetFile(platform_file, module_cache_spec); Index: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -18,7 +18,9 @@ #include "lldb/Core/Log.h" #include "lldb/Core/StreamString.h" #include "lldb/Host/File.h" +#include "lldb/Host/FileCache.h" #include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Target/ProcessLaunchInfo.h" @@ -121,7 +123,7 @@ Error &error) { if (IsHost()) - return Host::OpenFile(file_spec, flags, mode, error); + return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error); else if (m_remote_platform_sp) return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error); else @@ -132,7 +134,7 @@ PlatformPOSIX::CloseFile (lldb::user_id_t fd, Error &error) { if (IsHost()) - return Host::CloseFile(fd, error); + return FileCache::GetInstance().CloseFile(fd, error); else if (m_remote_platform_sp) return m_remote_platform_sp->CloseFile(fd, error); else @@ -147,7 +149,7 @@ Error &error) { if (IsHost()) - return Host::ReadFile(fd, offset, dst, dst_len, error); + return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error); else if (m_remote_platform_sp) return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error); else @@ -162,7 +164,7 @@ Error &error) { if (IsHost()) - return Host::WriteFile(fd, offset, src, src_len, error); + return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error); else if (m_remote_platform_sp) return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error); else @@ -350,7 +352,7 @@ PlatformPOSIX::GetFileSize (const FileSpec& file_spec) { if (IsHost()) - return Host::GetFileSize(file_spec); + return FileSystem::GetFileSize(file_spec); else if (m_remote_platform_sp) return m_remote_platform_sp->GetFileSize(file_spec); else @@ -361,7 +363,7 @@ PlatformPOSIX::CreateSymlink(const char *src, const char *dst) { if (IsHost()) - return Host::Symlink(src, dst); + return FileSystem::Symlink(src, dst); else if (m_remote_platform_sp) return m_remote_platform_sp->CreateSymlink(src, dst); else @@ -383,7 +385,7 @@ PlatformPOSIX::Unlink (const char *path) { if (IsHost()) - return Host::Unlink (path); + return FileSystem::Unlink(path); else if (m_remote_platform_sp) return m_remote_platform_sp->Unlink(path); else @@ -480,10 +482,9 @@ if (permissions == 0) permissions = lldb::eFilePermissionsFileDefault; - user_id_t fd_dst = Host::OpenFile(destination, - File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, - permissions, - error); + user_id_t fd_dst = FileCache::GetInstance().OpenFile( + destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, permissions, + error); if (fd_dst == UINT64_MAX) { @@ -507,15 +508,11 @@ break; if (n_read == 0) break; - if (Host::WriteFile(fd_dst, - offset, - buffer_sp->GetBytes(), - n_read, - error) != n_read) + if (FileCache::GetInstance().WriteFile(fd_dst, offset, buffer_sp->GetBytes(), n_read, error) != n_read) { if (!error.Fail()) error.SetErrorString("unable to write to destination file"); - break; + break; } offset += n_read; } @@ -524,7 +521,7 @@ if (fd_src != UINT64_MAX) CloseFile(fd_src, error); // And close the dst file descriptot. - if (fd_dst != UINT64_MAX && !Host::CloseFile(fd_dst, error)) + if (fd_dst != UINT64_MAX && !FileCache::GetInstance().CloseFile(fd_dst, error)) { if (!error.Fail()) error.SetErrorString("unable to close destination file"); Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -126,14 +126,14 @@ } const char * - GetFilePath (const lldb_private::FileAction *file_action, const char *default_path) + GetFilePath(const lldb_private::FileAction *file_action, const char *default_path) { const char *pts_name = "/dev/pts/"; const char *path = NULL; if (file_action) { - if (file_action->GetAction () == FileAction::eFileActionOpen) + if (file_action->GetAction() == FileAction::eFileActionOpen) { path = file_action->GetPath (); // By default the stdio paths passed in will be pseudo-terminal Index: lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h =================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h +++ lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h @@ -157,9 +157,7 @@ lldb_private::UnixSignals & GetUnixSignals(); - const char * - GetFilePath(const lldb_private::FileAction *file_action, - const char *default_path); + const char *GetFilePath(const lldb_private::FileAction *file_action, const char *default_path); /// Stops all threads in the process. /// The \p stop_tid parameter indicates the thread which initiated the stop. Index: lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -176,16 +176,14 @@ } const char * -ProcessPOSIX::GetFilePath( - const lldb_private::FileAction *file_action, - const char *default_path) +ProcessPOSIX::GetFilePath(const lldb_private::FileAction *file_action, const char *default_path) { const char *pts_name = "/dev/pts/"; const char *path = NULL; if (file_action) { - if (file_action->GetAction () == FileAction::eFileActionOpen) + if (file_action->GetAction() == FileAction::eFileActionOpen) { path = file_action->GetPath(); // By default the stdio paths passed in will be pseudo-terminal Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -22,6 +22,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" #include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/Socket.h" #include "lldb/Host/TimeValue.h" @@ -843,7 +844,7 @@ out_port = Args::StringToUInt32(port_cstr, 0); name_pipe_file.Close(); } - Host::Unlink(named_pipe_path); + FileSystem::Unlink(named_pipe_path); } else if (listen) { Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -31,6 +31,7 @@ #include "lldb/Host/Debug.h" #include "lldb/Host/Endian.h" #include "lldb/Host/File.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/TimeValue.h" #include "lldb/Target/FileAction.h" @@ -2498,7 +2499,7 @@ { std::string path; packet.GetHexByteString(path); - Error error = Host::MakeDirectory(path.c_str(),mode); + Error error = FileSystem::MakeDirectory(path.c_str(), mode); if (error.Success()) return SendPacketNoLock ("OK", 2); else @@ -2517,7 +2518,7 @@ { std::string path; packet.GetHexByteString(path); - Error error = Host::SetFilePermissions (path.c_str(), mode); + Error error = FileSystem::SetFilePermissions(path.c_str(), mode); if (error.Success()) return SendPacketNoLock ("OK", 2); else @@ -2667,7 +2668,7 @@ packet.GetHexByteString(path); if (!path.empty()) { - lldb::user_id_t retcode = Host::GetFileSize(FileSpec(path.c_str(), false)); + lldb::user_id_t retcode = FileSystem::GetFileSize(FileSpec(path.c_str(), false)); StreamString response; response.PutChar('F'); response.PutHex64(retcode); @@ -2708,7 +2709,7 @@ packet.GetHexByteString(path); if (!path.empty()) { - bool retcode = Host::GetFileExists(FileSpec(path.c_str(), false)); + bool retcode = FileSystem::GetFileExists(FileSpec(path.c_str(), false)); StreamString response; response.PutChar('F'); response.PutChar(','); @@ -2729,7 +2730,7 @@ packet.GetHexByteStringTerminatedBy(dst, ','); packet.GetChar(); // Skip ',' char packet.GetHexByteString(src); - Error error = Host::Symlink(src.c_str(), dst.c_str()); + Error error = FileSystem::Symlink(src.c_str(), dst.c_str()); StreamString response; response.Printf("F%u,%u", error.GetError(), error.GetError()); return SendPacketNoLock(response.GetData(), response.GetSize()); @@ -2741,7 +2742,7 @@ packet.SetFilePos(::strlen("vFile:unlink:")); std::string path; packet.GetHexByteString(path); - Error error = Host::Unlink(path.c_str()); + Error error = FileSystem::Unlink(path.c_str()); StreamString response; response.Printf("F%u,%u", error.GetError(), error.GetError()); return SendPacketNoLock(response.GetData(), response.GetSize()); @@ -2893,7 +2894,7 @@ { uint64_t a,b; StreamGDBRemote response; - if (Host::CalculateMD5(FileSpec(path.c_str(),false),a,b) == false) + if (FileSystem::CalculateMD5(FileSpec(path.c_str(), false), a, b) == false) { response.PutCString("F,"); response.PutCString("x"); Index: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -762,19 +762,19 @@ file_action = launch_info.GetFileActionForFD (STDIN_FILENO); if (file_action) { - if (file_action->GetAction () == FileAction::eFileActionOpen) + if (file_action->GetAction() == FileAction::eFileActionOpen) stdin_path = file_action->GetPath(); } file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); if (file_action) { - if (file_action->GetAction () == FileAction::eFileActionOpen) + if (file_action->GetAction() == FileAction::eFileActionOpen) stdout_path = file_action->GetPath(); } file_action = launch_info.GetFileActionForFD (STDERR_FILENO); if (file_action) { - if (file_action->GetAction () == FileAction::eFileActionOpen) + if (file_action->GetAction() == FileAction::eFileActionOpen) stderr_path = file_action->GetPath(); } Index: lldb/trunk/source/Target/FileAction.cpp =================================================================== --- lldb/trunk/source/Target/FileAction.cpp +++ lldb/trunk/source/Target/FileAction.cpp @@ -21,9 +21,16 @@ // FileAction member functions //---------------------------------------------------------------------------- -FileAction::FileAction() : m_action(eFileActionNone), m_fd(-1), m_arg(-1), m_path() {} +FileAction::FileAction() + : m_action(eFileActionNone) + , m_fd(-1) + , m_arg(-1) + , m_path() +{ +} -void FileAction::Clear() +void +FileAction::Clear() { m_action = eFileActionNone; m_fd = -1; @@ -31,14 +38,16 @@ m_path.clear(); } -const char *FileAction::GetPath() const +const char * +FileAction::GetPath() const { if (m_path.empty()) return NULL; return m_path.c_str(); } -bool FileAction::Open(int fd, const char *path, bool read, bool write) +bool +FileAction::Open(int fd, const char *path, bool read, bool write) { if ((read || write) && fd >= 0 && path && path[0]) { @@ -60,7 +69,8 @@ return false; } -bool FileAction::Close(int fd) +bool +FileAction::Close(int fd) { Clear(); if (fd >= 0) @@ -71,7 +81,8 @@ return m_fd >= 0; } -bool FileAction::Duplicate(int fd, int dup_fd) +bool +FileAction::Duplicate(int fd, int dup_fd) { Clear(); if (fd >= 0 && dup_fd >= 0) Index: lldb/trunk/source/Target/Platform.cpp =================================================================== --- lldb/trunk/source/Target/Platform.cpp +++ lldb/trunk/source/Target/Platform.cpp @@ -19,6 +19,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -494,8 +495,8 @@ dst_file.GetFilename() = src.GetFilename(); char buf[PATH_MAX]; - - rc_baton->error = Host::Readlink (src.GetPath().c_str(), buf, sizeof(buf)); + + rc_baton->error = FileSystem::Readlink(src.GetPath().c_str(), buf, sizeof(buf)); if (rc_baton->error.Fail()) return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out @@ -649,7 +650,7 @@ if (GetFileExists (fixed_dst)) Unlink (fixed_dst.GetPath().c_str()); char buf[PATH_MAX]; - error = Host::Readlink(src.GetPath().c_str(), buf, sizeof(buf)); + error = FileSystem::Readlink(src.GetPath().c_str(), buf, sizeof(buf)); if (error.Success()) error = CreateSymlink(dst.GetPath().c_str(), buf); } @@ -701,7 +702,7 @@ Platform::MakeDirectory (const char *path, uint32_t permissions) { if (IsHost()) - return Host::MakeDirectory (path, permissions); + return FileSystem::MakeDirectory(path, permissions); else { Error error; @@ -714,7 +715,7 @@ Platform::GetFilePermissions (const char *path, uint32_t &file_permissions) { if (IsHost()) - return Host::GetFilePermissions(path, file_permissions); + return FileSystem::GetFilePermissions(path, file_permissions); else { Error error; @@ -727,7 +728,7 @@ Platform::SetFilePermissions (const char *path, uint32_t file_permissions) { if (IsHost()) - return Host::SetFilePermissions(path, file_permissions); + return FileSystem::SetFilePermissions(path, file_permissions); else { Error error; @@ -1182,7 +1183,7 @@ uint64_t &high) { if (IsHost()) - return Host::CalculateMD5(file_spec, low, high); + return FileSystem::CalculateMD5(file_spec, low, high); else return false; } Index: lldb/trunk/source/Target/Process.cpp =================================================================== --- lldb/trunk/source/Target/Process.cpp +++ lldb/trunk/source/Target/Process.cpp @@ -402,45 +402,44 @@ break; case 'i': // STDIN for read only - { - FileAction action; - if (action.Open (STDIN_FILENO, option_arg, true, false)) - launch_info.AppendFileAction (action); - } + { + FileAction action; + if (action.Open (STDIN_FILENO, option_arg, true, false)) + launch_info.AppendFileAction (action); break; + } case 'o': // Open STDOUT for write only - { - FileAction action; - if (action.Open (STDOUT_FILENO, option_arg, false, true)) - launch_info.AppendFileAction (action); - } + { + FileAction action; + if (action.Open (STDOUT_FILENO, option_arg, false, true)) + launch_info.AppendFileAction (action); break; + } case 'e': // STDERR for write only - { - FileAction action; - if (action.Open (STDERR_FILENO, option_arg, false, true)) - launch_info.AppendFileAction (action); - } + { + FileAction action; + if (action.Open (STDERR_FILENO, option_arg, false, true)) + launch_info.AppendFileAction (action); break; - + } case 'p': // Process plug-in name launch_info.SetProcessPluginName (option_arg); break; case 'n': // Disable STDIO - { - FileAction action; - if (action.Open (STDIN_FILENO, "/dev/null", true, false)) - launch_info.AppendFileAction (action); - if (action.Open (STDOUT_FILENO, "/dev/null", false, true)) - launch_info.AppendFileAction (action); - if (action.Open (STDERR_FILENO, "/dev/null", false, true)) - launch_info.AppendFileAction (action); - } + { + FileAction action; + if (action.Open (STDIN_FILENO, "/dev/null", true, false)) + launch_info.AppendFileAction (action); + if (action.Open (STDOUT_FILENO, "/dev/null", false, true)) + launch_info.AppendFileAction (action); + if (action.Open (STDERR_FILENO, "/dev/null", false, true)) + launch_info.AppendFileAction (action); break; + } case 'w': launch_info.SetWorkingDirectory (option_arg); @@ -473,7 +472,6 @@ default: error.SetErrorStringWithFormat("unrecognized short option character '%c'", short_option); break; - } return error; } Index: lldb/trunk/source/Target/ProcessLaunchInfo.cpp =================================================================== --- lldb/trunk/source/Target/ProcessLaunchInfo.cpp +++ lldb/trunk/source/Target/ProcessLaunchInfo.cpp @@ -40,23 +40,20 @@ { } -ProcessLaunchInfo::ProcessLaunchInfo (const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - const char *working_directory, - uint32_t launch_flags) : - ProcessInfo(), - m_working_dir (), - m_plugin_name (), - m_shell (), - m_flags (launch_flags), - m_file_actions (), - m_pty (), - m_resume_count (0), - m_monitor_callback (NULL), - m_monitor_callback_baton (NULL), - m_monitor_signals (false), - m_hijack_listener_sp () +ProcessLaunchInfo::ProcessLaunchInfo(const char *stdin_path, const char *stdout_path, const char *stderr_path, + const char *working_directory, uint32_t launch_flags) + : ProcessInfo() + , m_working_dir() + , m_plugin_name() + , m_shell() + , m_flags(launch_flags) + , m_file_actions() + , m_pty() + , m_resume_count(0) + , m_monitor_callback(NULL) + , m_monitor_callback_baton(NULL) + , m_monitor_signals(false) + , m_hijack_listener_sp() { if (stdin_path) { @@ -135,7 +132,7 @@ } const FileAction * -ProcessLaunchInfo::GetFileActionAtIndex (size_t idx) const +ProcessLaunchInfo::GetFileActionAtIndex(size_t idx) const { if (idx < m_file_actions.size()) return &m_file_actions[idx]; @@ -143,7 +140,7 @@ } const FileAction * -ProcessLaunchInfo::GetFileActionForFD (int fd) const +ProcessLaunchInfo::GetFileActionForFD(int fd) const { for (size_t idx=0, count=m_file_actions.size(); idx < count; ++idx) {