diff options
| -rw-r--r-- | lldb/include/lldb/Host/FileSystem.h | 15 | ||||
| -rw-r--r-- | lldb/source/Host/common/File.cpp | 16 | ||||
| -rw-r--r-- | lldb/source/Host/common/Host.cpp | 4 | ||||
| -rw-r--r-- | lldb/source/Host/macosx/Host.mm | 3 | ||||
| -rw-r--r-- | lldb/source/Host/posix/DomainSocket.cpp | 4 | ||||
| -rw-r--r-- | lldb/source/Host/posix/FileSystem.cpp | 78 | ||||
| -rw-r--r-- | lldb/source/Host/posix/PipePosix.cpp | 3 | ||||
| -rw-r--r-- | lldb/source/Host/windows/FileSystem.cpp | 87 | ||||
| -rw-r--r-- | lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp | 11 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp | 15 | ||||
| -rw-r--r-- | lldb/source/Target/ModuleCache.cpp | 18 | ||||
| -rw-r--r-- | lldb/source/Target/Platform.cpp | 9 | 
12 files changed, 224 insertions, 39 deletions
diff --git a/lldb/include/lldb/Host/FileSystem.h b/lldb/include/lldb/Host/FileSystem.h index ffcb20b0247..c3ed4f7d715 100644 --- a/lldb/include/lldb/Host/FileSystem.h +++ b/lldb/include/lldb/Host/FileSystem.h @@ -26,15 +26,30 @@ public:    static const char *DEV_NULL;    static const char *PATH_CONVERSION_ERROR; +  static FileSpec::PathSyntax GetNativePathSyntax(); + +  static lldb::user_id_t GetFileSize(const FileSpec &file_spec); +  static bool GetFileExists(const FileSpec &file_spec); + +  static Error Hardlink(const FileSpec &src, const FileSpec &dst); +  static int GetHardlinkCount(const FileSpec &file_spec);    static Error Symlink(const FileSpec &src, const FileSpec &dst);    static Error Readlink(const FileSpec &src, FileSpec &dst); +  static Error Unlink(const FileSpec &file_spec);    static Error ResolveSymbolicLink(const FileSpec &src, FileSpec &dst); +  /// Return \b true if \a spec is on a locally mounted file system, \b false +  /// otherwise. +  static bool IsLocal(const FileSpec &spec); +    /// Wraps ::fopen in a platform-independent way. Once opened, FILEs can be    /// manipulated and closed with the normal ::fread, ::fclose, etc. functions.    static FILE *Fopen(const char *path, const char *mode); +  /// Wraps ::stat in a platform-independent way. +  static int Stat(const char *path, struct stat *stats); +    static llvm::sys::TimePoint<> GetModificationTime(const FileSpec &file_spec);  };  } diff --git a/lldb/source/Host/common/File.cpp b/lldb/source/Host/common/File.cpp index 36a931126b4..d7bb8582df6 100644 --- a/lldb/source/Host/common/File.cpp +++ b/lldb/source/Host/common/File.cpp @@ -24,11 +24,11 @@  #endif  #include "llvm/Support/ConvertUTF.h" -#include "llvm/Support/FileSystem.h"  #include "llvm/Support/Process.h" // for llvm::sys::Process::FileDescriptorHasColors()  #include "lldb/Host/Config.h"  #include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h"  #include "lldb/Utility/DataBufferHeap.h"  #include "lldb/Utility/Error.h"  #include "lldb/Utility/Log.h" @@ -249,12 +249,14 @@ Error File::Open(const char *path, uint32_t options, uint32_t permissions) {  uint32_t File::GetPermissions(const FileSpec &file_spec, Error &error) {    if (file_spec) { -    error.Clear(); -    auto Perms = llvm::sys::fs::getPermissions(file_spec.GetPath()); -    if (Perms) -      return *Perms; -    error = Error(Perms.getError()); -    return 0; +    struct stat file_stats; +    int stat_result = FileSystem::Stat(file_spec.GetCString(), &file_stats); +    if (stat_result == -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; diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index 649b2c96c2f..5d254ec0561 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -51,6 +51,7 @@  #include "lldb/Core/ArchSpec.h"  #include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h"  #include "lldb/Host/Host.h"  #include "lldb/Host/HostInfo.h"  #include "lldb/Host/HostProcess.h" @@ -597,7 +598,8 @@ Error Host::RunShellCommand(const Args &args, const FileSpec &working_dir,      }    } -  llvm::sys::fs::remove(output_file_spec.GetPath()); +  if (FileSystem::GetFileExists(output_file_spec)) +    FileSystem::Unlink(output_file_spec);    return error;  } diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm index bf39ae1adbf..700bce93c6d 100644 --- a/lldb/source/Host/macosx/Host.mm +++ b/lldb/source/Host/macosx/Host.mm @@ -62,6 +62,7 @@  #include "lldb/Core/StructuredData.h"  #include "lldb/Host/ConnectionFileDescriptor.h"  #include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h"  #include "lldb/Host/HostInfo.h"  #include "lldb/Host/ThreadLauncher.h"  #include "lldb/Target/Platform.h" @@ -529,7 +530,7 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path,      WaitForProcessToSIGSTOP(pid, 5);    } -  llvm::sys::fs::remove(unix_socket_name.GetPath()); +  FileSystem::Unlink(FileSpec{unix_socket_name, false});    [applescript release];    if (pid != LLDB_INVALID_PROCESS_ID)      launch_info.SetProcessID(pid); diff --git a/lldb/source/Host/posix/DomainSocket.cpp b/lldb/source/Host/posix/DomainSocket.cpp index 538979df2b6..cb0a1d05750 100644 --- a/lldb/source/Host/posix/DomainSocket.cpp +++ b/lldb/source/Host/posix/DomainSocket.cpp @@ -9,7 +9,7 @@  #include "lldb/Host/posix/DomainSocket.h" -#include "llvm/Support/FileSystem.h" +#include "lldb/Host/FileSystem.h"  #include <stddef.h>  #include <sys/socket.h> @@ -116,5 +116,5 @@ Error DomainSocket::Accept(llvm::StringRef name, bool child_processes_inherit,  size_t DomainSocket::GetNameOffset() const { return 0; }  void DomainSocket::DeleteSocketFile(llvm::StringRef name) { -  llvm::sys::fs::remove(name); +  FileSystem::Unlink(FileSpec{name, true});  } diff --git a/lldb/source/Host/posix/FileSystem.cpp b/lldb/source/Host/posix/FileSystem.cpp index 22f337fcfec..4c21fcd34a0 100644 --- a/lldb/source/Host/posix/FileSystem.cpp +++ b/lldb/source/Host/posix/FileSystem.cpp @@ -36,6 +36,33 @@ using namespace lldb_private;  const char *FileSystem::DEV_NULL = "/dev/null"; +FileSpec::PathSyntax FileSystem::GetNativePathSyntax() { +  return FileSpec::ePathSyntaxPosix; +} + +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::Hardlink(const FileSpec &src, const FileSpec &dst) { +  Error error; +  if (::link(dst.GetCString(), src.GetCString()) == -1) +    error.SetErrorToErrno(); +  return error; +} + +int FileSystem::GetHardlinkCount(const FileSpec &file_spec) { +  struct stat file_stat; +  if (::stat(file_spec.GetCString(), &file_stat) == 0) +    return file_stat.st_nlink; + +  return -1; +} +  Error FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {    Error error;    if (::symlink(dst.GetCString(), src.GetCString()) == -1) @@ -43,6 +70,13 @@ Error FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {    return error;  } +Error FileSystem::Unlink(const FileSpec &file_spec) { +  Error error; +  if (::unlink(file_spec.GetCString()) == -1) +    error.SetErrorToErrno(); +  return error; +} +  Error FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {    Error error;    char buf[PATH_MAX]; @@ -74,6 +108,50 @@ Error FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {    return Error();  } +#if defined(__NetBSD__) +static bool IsLocal(const struct statvfs &info) { +  return (info.f_flag & MNT_LOCAL) != 0; +} +#else +static bool IsLocal(const struct statfs &info) { +#ifdef __linux__ +#define CIFS_MAGIC_NUMBER 0xFF534D42 +  switch ((uint32_t)info.f_type) { +  case NFS_SUPER_MAGIC: +  case SMB_SUPER_MAGIC: +  case CIFS_MAGIC_NUMBER: +    return false; +  default: +    return true; +  } +#else +  return (info.f_flags & MNT_LOCAL) != 0; +#endif +} +#endif + +#if defined(__NetBSD__) +bool FileSystem::IsLocal(const FileSpec &spec) { +  struct statvfs statfs_info; +  std::string path(spec.GetPath()); +  if (statvfs(path.c_str(), &statfs_info) == 0) +    return ::IsLocal(statfs_info); +  return false; +} +#else +bool FileSystem::IsLocal(const FileSpec &spec) { +  struct statfs statfs_info; +  std::string path(spec.GetPath()); +  if (statfs(path.c_str(), &statfs_info) == 0) +    return ::IsLocal(statfs_info); +  return false; +} +#endif +  FILE *FileSystem::Fopen(const char *path, const char *mode) {    return ::fopen(path, mode);  } + +int FileSystem::Stat(const char *path, struct stat *stats) { +  return ::stat(path, stats); +} diff --git a/lldb/source/Host/posix/PipePosix.cpp b/lldb/source/Host/posix/PipePosix.cpp index 3ac5d480de8..4e0810c1a9b 100644 --- a/lldb/source/Host/posix/PipePosix.cpp +++ b/lldb/source/Host/posix/PipePosix.cpp @@ -8,6 +8,7 @@  //===----------------------------------------------------------------------===//  #include "lldb/Host/posix/PipePosix.h" +#include "lldb/Host/FileSystem.h"  #include "lldb/Host/HostInfo.h"  #include "lldb/Utility/SelectHelper.h"  #include "llvm/ADT/SmallString.h" @@ -230,7 +231,7 @@ void PipePosix::Close() {  }  Error PipePosix::Delete(llvm::StringRef name) { -  return llvm::sys::fs::remove(name); +  return FileSystem::Unlink(FileSpec{name.data(), true});  }  bool PipePosix::CanRead() const { diff --git a/lldb/source/Host/windows/FileSystem.cpp b/lldb/source/Host/windows/FileSystem.cpp index 907c0c9337a..e834c85a28c 100644 --- a/lldb/source/Host/windows/FileSystem.cpp +++ b/lldb/source/Host/windows/FileSystem.cpp @@ -26,6 +26,49 @@ const char *FileSystem::DEV_NULL = "nul";  const char *FileSystem::PATH_CONVERSION_ERROR =      "Error converting path between UTF-8 and native encoding"; +FileSpec::PathSyntax FileSystem::GetNativePathSyntax() { +  return FileSpec::ePathSyntaxWindows; +} + +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::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; +} + +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::Symlink(const FileSpec &src, const FileSpec &dst) {    Error error;    std::wstring wsrc, wdst; @@ -47,6 +90,19 @@ Error FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {    return error;  } +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; +} +  Error FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {    Error error;    std::wstring wsrc; @@ -84,6 +140,15 @@ Error FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {    return Error("ResolveSymbolicLink() isn't implemented on Windows");  } +bool FileSystem::IsLocal(const FileSpec &spec) { +  if (spec) { +    // TODO: return true if the file is on a locally mounted file system +    return true; +  } + +  return false; +} +  FILE *FileSystem::Fopen(const char *path, const char *mode) {    std::wstring wpath, wmode;    if (!llvm::ConvertUTF8toWide(path, wpath)) @@ -95,3 +160,25 @@ FILE *FileSystem::Fopen(const char *path, const char *mode) {      return nullptr;    return file;  } + +int FileSystem::Stat(const char *path, struct stat *stats) { +  std::wstring wpath; +  if (!llvm::ConvertUTF8toWide(path, wpath)) { +    errno = EINVAL; +    return -EINVAL; +  } +  int stat_result; +#ifdef _USE_32BIT_TIME_T +  struct _stat32 file_stats; +  stat_result = ::_wstat32(wpath.c_str(), &file_stats); +#else +  struct _stat64i32 file_stats; +  stat_result = ::_wstat64i32(wpath.c_str(), &file_stats); +#endif +  if (stat_result == 0) { +    static_assert(sizeof(struct stat) == sizeof(file_stats), +                  "stat and _stat32/_stat64i32 must have the same layout"); +    *stats = *reinterpret_cast<struct stat *>(&file_stats); +  } +  return stat_result; +} diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp index c6ce3efc8cc..fe1b1056da1 100644 --- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -435,12 +435,9 @@ PlatformPOSIX::PutFile(const lldb_private::FileSpec &source,  }  lldb::user_id_t PlatformPOSIX::GetFileSize(const FileSpec &file_spec) { -  if (IsHost()) { -    uint64_t Size; -    if (llvm::sys::fs::file_size(file_spec.GetPath(), Size)) -      return 0; -    return Size; -  } else if (m_remote_platform_sp) +  if (IsHost()) +    return FileSystem::GetFileSize(file_spec); +  else if (m_remote_platform_sp)      return m_remote_platform_sp->GetFileSize(file_spec);    else      return Platform::GetFileSize(file_spec); @@ -466,7 +463,7 @@ bool PlatformPOSIX::GetFileExists(const FileSpec &file_spec) {  Error PlatformPOSIX::Unlink(const FileSpec &file_spec) {    if (IsHost()) -    return llvm::sys::fs::remove(file_spec.GetPath()); +    return FileSystem::Unlink(file_spec);    else if (m_remote_platform_sp)      return m_remote_platform_sp->Unlink(file_spec);    else diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index 5b20713f18f..758ece5b85e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -642,15 +642,14 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Size(    std::string path;    packet.GetHexByteString(path);    if (!path.empty()) { -    uint64_t Size; -    if (llvm::sys::fs::file_size(path, Size)) -      return SendErrorResponse(5); +    lldb::user_id_t retcode = FileSystem::GetFileSize(FileSpec(path, false));      StreamString response;      response.PutChar('F'); -    response.PutHex64(Size); -    if (Size == UINT64_MAX) { +    response.PutHex64(retcode); +    if (retcode == UINT64_MAX) {        response.PutChar(','); -      response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode() +      response.PutHex64( +          retcode); // TODO: replace with Host::GetSyswideErrorCode()      }      return SendPacketNoLock(response.GetString());    } @@ -682,7 +681,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Exists(    std::string path;    packet.GetHexByteString(path);    if (!path.empty()) { -    bool retcode = llvm::sys::fs::exists(path); +    bool retcode = FileSystem::GetFileExists(FileSpec(path, false));      StreamString response;      response.PutChar('F');      response.PutChar(','); @@ -715,7 +714,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_unlink(    packet.SetFilePos(::strlen("vFile:unlink:"));    std::string path;    packet.GetHexByteString(path); -  Error error(llvm::sys::fs::remove(path)); +  Error error = FileSystem::Unlink(FileSpec{path, true});    StreamString response;    response.Printf("F%u,%u", error.GetError(), error.GetError());    return SendPacketNoLock(response.GetString()); diff --git a/lldb/source/Target/ModuleCache.cpp b/lldb/source/Target/ModuleCache.cpp index a4aa26a0e48..b35e2d79b20 100644 --- a/lldb/source/Target/ModuleCache.cpp +++ b/lldb/source/Target/ModuleCache.cpp @@ -13,6 +13,7 @@  #include "lldb/Core/ModuleList.h"  #include "lldb/Core/ModuleSpec.h"  #include "lldb/Host/File.h" +#include "lldb/Host/FileSystem.h"  #include "lldb/Host/LockFile.h"  #include "lldb/Utility/Log.h"  #include "llvm/Support/FileSystem.h" @@ -100,12 +101,11 @@ void DeleteExistingModule(const FileSpec &root_dir_spec,                    module_uuid.GetAsString().c_str(), error.AsCString());    } -  namespace fs = llvm::sys::fs; -  fs::file_status st; -  if (status(sysroot_module_path_spec.GetPath(), st)) +  auto link_count = FileSystem::GetHardlinkCount(sysroot_module_path_spec); +  if (link_count == -1)      return; -  if (st.getLinkCount() > 2) // module is referred by other hosts. +  if (link_count > 2) // module is referred by other hosts.      return;    const auto module_spec_dir = GetModuleDirectory(root_dir_spec, module_uuid); @@ -119,10 +119,11 @@ void DecrementRefExistingModule(const FileSpec &root_dir_spec,    DeleteExistingModule(root_dir_spec, sysroot_module_path_spec);    // Remove sysroot link. -  llvm::sys::fs::remove(sysroot_module_path_spec.GetPath()); +  FileSystem::Unlink(sysroot_module_path_spec);    FileSpec symfile_spec = GetSymbolFileSpec(sysroot_module_path_spec); -  llvm::sys::fs::remove(symfile_spec.GetPath()); +  if (symfile_spec.Exists()) // delete module's symbol file if exists. +    FileSystem::Unlink(symfile_spec);  }  Error CreateHostSysRootModuleLink(const FileSpec &root_dir_spec, @@ -145,8 +146,7 @@ Error CreateHostSysRootModuleLink(const FileSpec &root_dir_spec,    if (error.Fail())      return error; -  return llvm::sys::fs::create_hard_link(local_module_spec.GetPath(), -                                         sysroot_module_path_spec.GetPath()); +  return FileSystem::Hardlink(sysroot_module_path_spec, local_module_spec);  }  } // namespace @@ -179,7 +179,7 @@ void ModuleLock::Delete() {      return;    m_file.Close(); -  llvm::sys::fs::remove(m_file_spec.GetPath()); +  FileSystem::Unlink(m_file_spec);  }  ///////////////////////////////////////////////////////////////////////// diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index acafa8b35c5..ac8a168b93e 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -696,7 +696,8 @@ Error Platform::Install(const FileSpec &src, const FileSpec &dst) {      namespace fs = llvm::sys::fs;      switch (fs::get_file_type(src.GetPath(), false)) {      case fs::file_type::directory_file: { -      llvm::sys::fs::remove(fixed_dst.GetPath()); +      if (GetFileExists(fixed_dst)) +        Unlink(fixed_dst);        uint32_t permissions = src.GetPermissions();        if (permissions == 0)          permissions = eFilePermissionsDirectoryDefault; @@ -715,12 +716,14 @@ Error Platform::Install(const FileSpec &src, const FileSpec &dst) {      } break;      case fs::file_type::regular_file: -      llvm::sys::fs::remove(fixed_dst.GetPath()); +      if (GetFileExists(fixed_dst)) +        Unlink(fixed_dst);        error = PutFile(src, fixed_dst);        break;      case fs::file_type::symlink_file: { -      llvm::sys::fs::remove(fixed_dst.GetPath()); +      if (GetFileExists(fixed_dst)) +        Unlink(fixed_dst);        FileSpec src_resolved;        error = FileSystem::Readlink(src, src_resolved);        if (error.Success())  | 

