From 81502e6c7df732b9caf6cf2cc34082ed7abe3618 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Mon, 1 Apr 2024 20:52:57 +1000 Subject: [PATCH] FileSystem: Add Error to CreateDirectory()/RenamePath() --- common/FileSystem.cpp | 74 ++++++++++++++++++++++++++++++------------- common/FileSystem.h | 8 +++-- 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/common/FileSystem.cpp b/common/FileSystem.cpp index ad870cac24..467f145817 100644 --- a/common/FileSystem.cpp +++ b/common/FileSystem.cpp @@ -8,6 +8,7 @@ #include "Console.h" #include "StringUtil.h" #include "Path.h" + #include #include #include @@ -1182,13 +1183,13 @@ bool FileSystem::WriteStringToFile(const char* filename, const std::string_view& return true; } -bool FileSystem::EnsureDirectoryExists(const char* path, bool recursive) +bool FileSystem::EnsureDirectoryExists(const char* path, bool recursive, Error* error) { if (FileSystem::DirectoryExists(path)) return true; // if it fails to create, we're not going to be able to use it anyway - return FileSystem::CreateDirectoryPath(path, recursive); + return FileSystem::CreateDirectoryPath(path, recursive, error); } bool FileSystem::RecursiveDeleteDirectory(const char* path) @@ -1633,33 +1634,39 @@ bool FileSystem::DirectoryIsEmpty(const char* path) return true; } -bool FileSystem::CreateDirectoryPath(const char* Path, bool Recursive) +bool FileSystem::CreateDirectoryPath(const char* Path, bool Recursive, Error* error) { const std::wstring wpath = GetWin32Path(Path); // has a path - if (wpath.empty()) + if (wpath.empty()) [[unlikely]] + { + Error::SetStringView(error, "Path is empty."); return false; + } // try just flat-out, might work if there's no other segments that have to be made if (CreateDirectoryW(wpath.c_str(), nullptr)) return true; - if (!Recursive) - return false; - // check error DWORD lastError = GetLastError(); if (lastError == ERROR_ALREADY_EXISTS) { // check the attributes - u32 Attributes = GetFileAttributesW(wpath.c_str()); + const u32 Attributes = GetFileAttributesW(wpath.c_str()); if (Attributes != INVALID_FILE_ATTRIBUTES && Attributes & FILE_ATTRIBUTE_DIRECTORY) return true; - else - return false; } - else if (lastError == ERROR_PATH_NOT_FOUND) + + if (!Recursive) + { + Error::SetWin32(error, "CreateDirectoryW() failed: ", lastError); + return false; + } + + // check error + if (lastError == ERROR_PATH_NOT_FOUND) { // part of the path does not exist, so we'll create the parent folders, then // the full path again. @@ -1677,7 +1684,10 @@ bool FileSystem::CreateDirectoryPath(const char* Path, bool Recursive) { lastError = GetLastError(); if (lastError != ERROR_ALREADY_EXISTS) // fine, continue to next path segment + { + Error::SetWin32(error, "CreateDirectoryW() failed: ", lastError); return false; + } } // replace / with \. @@ -1697,7 +1707,10 @@ bool FileSystem::CreateDirectoryPath(const char* Path, bool Recursive) { lastError = GetLastError(); if (lastError != ERROR_ALREADY_EXISTS) + { + Error::SetWin32(error, "CreateDirectoryW() failed: ", lastError); return false; + } } } @@ -1707,6 +1720,7 @@ bool FileSystem::CreateDirectoryPath(const char* Path, bool Recursive) else { // unhandled error + Error::SetWin32(error, "CreateDirectoryW() failed: ", lastError); return false; } } @@ -1724,14 +1738,16 @@ bool FileSystem::DeleteFilePath(const char* path) return (DeleteFileW(wpath.c_str()) == TRUE); } -bool FileSystem::RenamePath(const char* old_path, const char* new_path) +bool FileSystem::RenamePath(const char* old_path, const char* new_path, Error* error) { const std::wstring old_wpath = GetWin32Path(old_path); const std::wstring new_wpath = GetWin32Path(new_path); if (!MoveFileExW(old_wpath.c_str(), new_wpath.c_str(), MOVEFILE_REPLACE_EXISTING)) { - Console.Error("MoveFileEx('%s', '%s') failed: %08X", old_path, new_path, GetLastError()); + const DWORD err = GetLastError(); + Error::SetWin32(error, "MoveFileExW() failed: ", err); + Console.Error("MoveFileEx('%s', '%s') failed: %08X", old_path, new_path, err); return false; } @@ -2119,7 +2135,7 @@ bool FileSystem::DirectoryIsEmpty(const char* path) return true; } -bool FileSystem::CreateDirectoryPath(const char* path, bool recursive) +bool FileSystem::CreateDirectoryPath(const char* path, bool recursive, Error* error) { // has a path const size_t pathLength = std::strlen(path); @@ -2130,9 +2146,6 @@ bool FileSystem::CreateDirectoryPath(const char* path, bool recursive) if (mkdir(path, 0777) == 0) return true; - if (!recursive) - return false; - // check error int lastError = errno; if (lastError == EEXIST) @@ -2141,10 +2154,15 @@ bool FileSystem::CreateDirectoryPath(const char* path, bool recursive) struct stat sysStatData; if (stat(path, &sysStatData) == 0 && S_ISDIR(sysStatData.st_mode)) return true; - else - return false; } - else if (lastError == ENOENT) + + if (!recursive) + { + Error::SetErrno(error, "mkdir() failed: ", lastError); + return false; + } + + if (lastError == ENOENT) { // part of the path does not exist, so we'll create the parent folders, then // the full path again. @@ -2160,7 +2178,10 @@ bool FileSystem::CreateDirectoryPath(const char* path, bool recursive) { lastError = errno; if (lastError != EEXIST) // fine, continue to next path segment + { + Error::SetErrno(error, "mkdir() failed: ", lastError); return false; + } } } @@ -2174,7 +2195,10 @@ bool FileSystem::CreateDirectoryPath(const char* path, bool recursive) { lastError = errno; if (lastError != EEXIST) + { + Error::SetErrno(error, "mkdir() failed: ", lastError); return false; + } } } @@ -2184,6 +2208,7 @@ bool FileSystem::CreateDirectoryPath(const char* path, bool recursive) else { // unhandled error + Error::SetErrno(error, "mkdir() failed: ", lastError); return false; } } @@ -2200,14 +2225,19 @@ bool FileSystem::DeleteFilePath(const char* path) return (unlink(path) == 0); } -bool FileSystem::RenamePath(const char* old_path, const char* new_path) +bool FileSystem::RenamePath(const char* old_path, const char* new_path, Error* error) { if (old_path[0] == '\0' || new_path[0] == '\0') + { + Error::SetStringView(error, "Path is empty."); return false; + } if (rename(old_path, new_path) != 0) { - Console.Error("rename('%s', '%s') failed: %d", old_path, new_path, errno); + const int err = errno; + Error::SetErrno(error, "rename() failed: ", err); + Console.Error("rename('%s', '%s') failed: %d", old_path, new_path, err); return false; } diff --git a/common/FileSystem.h b/common/FileSystem.h index ed7b897eed..f7672c5aa6 100644 --- a/common/FileSystem.h +++ b/common/FileSystem.h @@ -2,7 +2,9 @@ // SPDX-License-Identifier: LGPL-3.0+ #pragma once + #include "Pcsx2Defs.h" + #include #include #include @@ -88,7 +90,7 @@ namespace FileSystem bool DeleteFilePath(const char* path); /// Rename file - bool RenamePath(const char* OldPath, const char* NewPath); + bool RenamePath(const char* OldPath, const char* NewPath, Error* error = nullptr); /// Deleter functor for managed file pointers struct FileDeleter @@ -134,11 +136,11 @@ namespace FileSystem /// if the directory already exists, the return value will be true. /// if Recursive is specified, all parent directories will be created /// if they do not exist. - bool CreateDirectoryPath(const char* path, bool recursive); + bool CreateDirectoryPath(const char* path, bool recursive, Error* error = nullptr); /// Creates a directory if it doesn't already exist. /// Returns false if it does not exist and creation failed. - bool EnsureDirectoryExists(const char* path, bool recursive); + bool EnsureDirectoryExists(const char* path, bool recursive, Error* error = nullptr); /// Removes a directory. bool DeleteDirectory(const char* path);