Move FileSystem functions out of Host and into their own classes.
More specifically, this change can be summarized as follows:
1) Makes an lldbHostPosix library which contains code common to
all posix platforms.
2) Creates Host/FileSystem.h which defines a common FileSystem
interface.
3) Implements FileSystem.h in Host/windows and Host/posix.
4) Creates Host/FileCache.h, implemented in Host/common, which
defines a class useful for storing handles to open files needed
by the debugger.
Differential Revision: http://reviews.llvm.org/D4889
llvm-svn: 215775
diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt
index d203d0b..5f8a2f6 100644
--- a/lldb/source/Host/CMakeLists.txt
+++ b/lldb/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()
diff --git a/lldb/source/Host/common/CMakeLists.txt b/lldb/source/Host/common/CMakeLists.txt
index 2e355ee..d71f18d 100644
--- a/lldb/source/Host/common/CMakeLists.txt
+++ b/lldb/source/Host/common/CMakeLists.txt
@@ -5,6 +5,7 @@
DynamicLibrary.cpp
Editline.cpp
File.cpp
+ FileCache.cpp
FileSpec.cpp
Host.cpp
IOObject.cpp
diff --git a/lldb/source/Host/common/FileCache.cpp b/lldb/source/Host/common/FileCache.cpp
new file mode 100644
index 0000000..96b2a2e
--- /dev/null
+++ b/lldb/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<uint64_t>(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<uint64_t>(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;
+}
diff --git a/lldb/source/Host/common/FileSpec.cpp b/lldb/source/Host/common/FileSpec.cpp
index 56179a3..8c4014c 100644
--- a/lldb/source/Host/common/FileSpec.cpp
+++ b/lldb/source/Host/common/FileSpec.cpp
@@ -27,22 +27,22 @@
#include <pwd.h>
#endif
+#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"
-#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/Stream.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Utility/CleanUp.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<char> &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<char> &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;
}
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index 33df16f..885104fec 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/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<void *>(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<void *>(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<void *>(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<void *>(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<void *>(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<void *>(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<size_t>(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<lldb::user_id_t, lldb::FileSP> 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<uint64_t>(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<uint64_t>(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
-}
diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp
index 86bea42..31e3228 100644
--- a/lldb/source/Host/common/Socket.cpp
+++ b/lldb/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)
{
diff --git a/lldb/source/Host/posix/CMakeLists.txt b/lldb/source/Host/posix/CMakeLists.txt
new file mode 100644
index 0000000..c783764
--- /dev/null
+++ b/lldb/source/Host/posix/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbHostPosix
+ FileSystem.cpp
+ )
diff --git a/lldb/source/Host/posix/FileSystem.cpp b/lldb/source/Host/posix/FileSystem.cpp
new file mode 100644
index 0000000..5713168
--- /dev/null
+++ b/lldb/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 <sys/stat.h>
+#include <sys/types.h>
+
+// 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<size_t>(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
+}
diff --git a/lldb/source/Host/windows/CMakeLists.txt b/lldb/source/Host/windows/CMakeLists.txt
index 2a19922..5a5ce2a 100644
--- a/lldb/source/Host/windows/CMakeLists.txt
+++ b/lldb/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
diff --git a/lldb/source/Host/windows/FileSystem.cpp b/lldb/source/Host/windows/FileSystem.cpp
new file mode 100644
index 0000000..a735ff0
--- /dev/null
+++ b/lldb/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 <shellapi.h>
+
+#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;
+}
diff --git a/lldb/source/Host/windows/Host.cpp b/lldb/source/Host/windows/Host.cpp
index bf6c1bd..9fa2652 100644
--- a/lldb/source/Host/windows/Host.cpp
+++ b/lldb/source/Host/windows/Host.cpp
@@ -25,7 +25,6 @@
#include "lldb/Core/StreamFile.h"
// Windows includes
-#include <shellapi.h>
#include <TlHelp32.h>
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;