diff options
Diffstat (limited to 'source/Host/windows/FileSystem.cpp')
-rw-r--r-- | source/Host/windows/FileSystem.cpp | 418 |
1 files changed, 193 insertions, 225 deletions
diff --git a/source/Host/windows/FileSystem.cpp b/source/Host/windows/FileSystem.cpp index 3e881f5d9b2b..f0ba7376876d 100644 --- a/source/Host/windows/FileSystem.cpp +++ b/source/Host/windows/FileSystem.cpp @@ -21,273 +21,241 @@ using namespace lldb_private; -const char * -FileSystem::DEV_NULL = "nul"; +const char *FileSystem::DEV_NULL = "nul"; -const char *FileSystem::PATH_CONVERSION_ERROR = "Error converting path between UTF-8 and native encoding"; +const char *FileSystem::PATH_CONVERSION_ERROR = + "Error converting path between UTF-8 and native encoding"; -FileSpec::PathSyntax -FileSystem::GetNativePathSyntax() -{ - return FileSpec::ePathSyntaxWindows; +FileSpec::PathSyntax FileSystem::GetNativePathSyntax() { + return FileSpec::ePathSyntaxWindows; } -Error -FileSystem::MakeDirectory(const FileSpec &file_spec, 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(file_spec.GetPath(), true); - if (err_code) - { - error.SetErrorString(err_code.message().c_str()); - } - - return error; +Error FileSystem::MakeDirectory(const FileSpec &file_spec, + 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(file_spec.GetPath(), true); + if (err_code) { + error.SetErrorString(err_code.message().c_str()); + } + + return error; } -Error -FileSystem::DeleteDirectory(const FileSpec &file_spec, bool recurse) -{ - Error error; - std::wstring path_buffer; - if (!llvm::ConvertUTF8toWide(file_spec.GetPath(), path_buffer)) - { - error.SetErrorString(PATH_CONVERSION_ERROR); - return error; - } - if (!recurse) - { - BOOL result = ::RemoveDirectoryW(path_buffer.c_str()); - 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. The first null terminator is there only in the backing - // store but not the actual vector contents, and so we need to push twice. - path_buffer.push_back(0); - path_buffer.push_back(0); - - SHFILEOPSTRUCTW shfos = {0}; - shfos.wFunc = FO_DELETE; - shfos.pFrom = (LPCWSTR)path_buffer.data(); - shfos.fFlags = FOF_NO_UI; - - int result = ::SHFileOperationW(&shfos); - // TODO(zturner): Correctly handle the intricacies of SHFileOperation return values. - if (result != 0) - error.SetErrorStringWithFormat("SHFileOperation failed"); - } +Error FileSystem::DeleteDirectory(const FileSpec &file_spec, bool recurse) { + Error error; + std::wstring path_buffer; + if (!llvm::ConvertUTF8toWide(file_spec.GetPath(), path_buffer)) { + error.SetErrorString(PATH_CONVERSION_ERROR); return error; + } + if (!recurse) { + BOOL result = ::RemoveDirectoryW(path_buffer.c_str()); + 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. The first null terminator is there only in + // the backing + // store but not the actual vector contents, and so we need to push twice. + path_buffer.push_back(0); + path_buffer.push_back(0); + + SHFILEOPSTRUCTW shfos = {}; + shfos.wFunc = FO_DELETE; + shfos.pFrom = (LPCWSTR)path_buffer.data(); + shfos.fFlags = FOF_NO_UI; + + int result = ::SHFileOperationW(&shfos); + // TODO(zturner): Correctly handle the intricacies of SHFileOperation return + // values. + if (result != 0) + error.SetErrorStringWithFormat("SHFileOperation failed"); + } + return error; } -Error -FileSystem::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions) -{ - Error error; - // Beware that Windows's permission model is different from Unix's, and it's - // not clear if this API is supposed to check ACLs. To match the caller's - // expectations as closely as possible, we'll use Microsoft's _stat, which - // attempts to emulate POSIX stat. This should be good enough for basic - // checks like FileSpec::Readable. - struct _stat file_stats; - if (::_stat(file_spec.GetCString(), &file_stats) == 0) - { - // The owner permission bits in "st_mode" currently match the definitions - // for the owner file mode bits. - file_permissions = file_stats.st_mode & (_S_IREAD | _S_IWRITE | _S_IEXEC); - } - else - { - error.SetErrorToErrno(); - } - - return error; +Error FileSystem::GetFilePermissions(const FileSpec &file_spec, + uint32_t &file_permissions) { + Error error; + // Beware that Windows's permission model is different from Unix's, and it's + // not clear if this API is supposed to check ACLs. To match the caller's + // expectations as closely as possible, we'll use Microsoft's _stat, which + // attempts to emulate POSIX stat. This should be good enough for basic + // checks like FileSpec::Readable. + struct _stat file_stats; + if (::_stat(file_spec.GetCString(), &file_stats) == 0) { + // The owner permission bits in "st_mode" currently match the definitions + // for the owner file mode bits. + file_permissions = file_stats.st_mode & (_S_IREAD | _S_IWRITE | _S_IEXEC); + } else { + error.SetErrorToErrno(); + } + + return error; } -Error -FileSystem::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions) -{ - Error error; - error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__); - return error; +Error FileSystem::SetFilePermissions(const FileSpec &file_spec, + uint32_t file_permissions) { + Error error; + error.SetErrorStringWithFormat("%s is not supported on this host", + LLVM_PRETTY_FUNCTION); + return error; } -lldb::user_id_t -FileSystem::GetFileSize(const FileSpec &file_spec) -{ - return file_spec.GetByteSize(); +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(); +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; +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; +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); + 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; + 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; + AutoHandle auto_file_handle(file_handle); + BY_HANDLE_FILE_INFORMATION file_info; + if (::GetFileInformationByHandle(file_handle, &file_info)) + return file_info.nNumberOfLinks; - return -1; + return -1; } -Error -FileSystem::Symlink(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); - if (error.Fail()) - return error; - DWORD attrib = ::GetFileAttributesW(wdst.c_str()); - if (attrib == INVALID_FILE_ATTRIBUTES) - { - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); - return error; - } - bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY); - DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; - BOOL result = ::CreateSymbolicLinkW(wsrc.c_str(), wdst.c_str(), flag); - if (!result) - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); +Error FileSystem::Symlink(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); + if (error.Fail()) + return error; + DWORD attrib = ::GetFileAttributesW(wdst.c_str()); + if (attrib == INVALID_FILE_ATTRIBUTES) { + error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; + } + bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY); + DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; + BOOL result = ::CreateSymbolicLinkW(wsrc.c_str(), wdst.c_str(), flag); + if (!result) + error.SetError(::GetLastError(), lldb::eErrorTypeWin32); + return error; } -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); +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; - if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc)) - { - error.SetErrorString(PATH_CONVERSION_ERROR); - return error; - } - - HANDLE h = ::CreateFileW(wsrc.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT, NULL); - if (h == INVALID_HANDLE_VALUE) - { - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); - return error; - } - - std::vector<wchar_t> buf(PATH_MAX + 1); - // Subtract 1 from the path length since this function does not add a null terminator. - DWORD result = ::GetFinalPathNameByHandleW(h, buf.data(), buf.size() - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); - std::string path; - if (result == 0) - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); - else if (!llvm::convertWideToUTF8(buf.data(), path)) - error.SetErrorString(PATH_CONVERSION_ERROR); - else - dst.SetFile(path, false); - - ::CloseHandle(h); +Error FileSystem::Readlink(const FileSpec &src, FileSpec &dst) { + Error error; + std::wstring wsrc; + if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc)) { + error.SetErrorString(PATH_CONVERSION_ERROR); + return error; + } + + HANDLE h = ::CreateFileW(wsrc.c_str(), GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL); + if (h == INVALID_HANDLE_VALUE) { + error.SetError(::GetLastError(), lldb::eErrorTypeWin32); return error; + } + + std::vector<wchar_t> buf(PATH_MAX + 1); + // Subtract 1 from the path length since this function does not add a null + // terminator. + DWORD result = ::GetFinalPathNameByHandleW( + h, buf.data(), buf.size() - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); + std::string path; + if (result == 0) + error.SetError(::GetLastError(), lldb::eErrorTypeWin32); + else if (!llvm::convertWideToUTF8(buf.data(), path)) + error.SetErrorString(PATH_CONVERSION_ERROR); + else + dst.SetFile(path, false); + + ::CloseHandle(h); + return error; } -Error -FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) -{ - return Error("ResolveSymbolicLink() isn't implemented on Windows"); +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; - } +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; + return false; } -FILE * -FileSystem::Fopen(const char *path, const char *mode) -{ - std::wstring wpath, wmode; - if (!llvm::ConvertUTF8toWide(path, wpath)) - return nullptr; - if (!llvm::ConvertUTF8toWide(mode, wmode)) - return nullptr; - FILE *file; - if (_wfopen_s(&file, wpath.c_str(), wmode.c_str()) != 0) - return nullptr; - return file; +FILE *FileSystem::Fopen(const char *path, const char *mode) { + std::wstring wpath, wmode; + if (!llvm::ConvertUTF8toWide(path, wpath)) + return nullptr; + if (!llvm::ConvertUTF8toWide(mode, wmode)) + return nullptr; + FILE *file; + if (_wfopen_s(&file, wpath.c_str(), wmode.c_str()) != 0) + 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; +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); + 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); + 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; + 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; } |