forked from OSchip/llvm-project
167 lines
4.4 KiB
C++
167 lines
4.4 KiB
C++
//===-- 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"
|
|
#include "llvm/Support/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;
|
|
const auto err_code = llvm::sys::fs::create_directories(path, true);
|
|
if (err_code)
|
|
{
|
|
error.SetErrorString(err_code.message().c_str());
|
|
}
|
|
|
|
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::Hardlink(const char *linkname, const char *target)
|
|
{
|
|
Error error;
|
|
if (!::CreateHardLink(linkname, target, nullptr))
|
|
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
|
|
return error;
|
|
}
|
|
|
|
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::IsLocal(const FileSpec &spec)
|
|
{
|
|
if (spec)
|
|
{
|
|
// TODO: return true if the file is on a locally mounted file system
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|