mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 15:45:42 +00:00
FileSystem: Add Error to CreateDirectory()/RenamePath()
This commit is contained in:
parent
3ecc19c43f
commit
eb504143c1
|
@ -1201,13 +1201,13 @@ bool FileSystem::WriteStringToFile(const char* filename, const std::string_view&
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystem::EnsureDirectoryExists(const char* path, bool recursive)
|
bool FileSystem::EnsureDirectoryExists(const char* path, bool recursive, Error* error)
|
||||||
{
|
{
|
||||||
if (FileSystem::DirectoryExists(path))
|
if (FileSystem::DirectoryExists(path))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// if it fails to create, we're not going to be able to use it anyway
|
// if it fails to create, we're not going to be able to use it anyway
|
||||||
return FileSystem::CreateDirectory(path, recursive);
|
return FileSystem::CreateDirectory(path, recursive, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystem::RecursiveDeleteDirectory(const char* path)
|
bool FileSystem::RecursiveDeleteDirectory(const char* path)
|
||||||
|
@ -1654,31 +1654,36 @@ bool FileSystem::DirectoryIsEmpty(const char* path)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystem::CreateDirectory(const char* Path, bool Recursive)
|
bool FileSystem::CreateDirectory(const char* Path, bool Recursive, Error* error)
|
||||||
{
|
{
|
||||||
const std::wstring win32_path = GetWin32Path(Path);
|
const std::wstring win32_path = GetWin32Path(Path);
|
||||||
if (win32_path.empty())
|
if (win32_path.empty()) [[unlikely]]
|
||||||
|
{
|
||||||
|
Error::SetStringView(error, "Path is empty.");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// try just flat-out, might work if there's no other segments that have to be made
|
// try just flat-out, might work if there's no other segments that have to be made
|
||||||
if (CreateDirectoryW(win32_path.c_str(), nullptr))
|
if (CreateDirectoryW(win32_path.c_str(), nullptr))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!Recursive)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// check error
|
|
||||||
DWORD lastError = GetLastError();
|
DWORD lastError = GetLastError();
|
||||||
if (lastError == ERROR_ALREADY_EXISTS)
|
if (lastError == ERROR_ALREADY_EXISTS)
|
||||||
{
|
{
|
||||||
// check the attributes
|
// check the attributes
|
||||||
u32 Attributes = GetFileAttributesW(win32_path.c_str());
|
const u32 Attributes = GetFileAttributesW(win32_path.c_str());
|
||||||
if (Attributes != INVALID_FILE_ATTRIBUTES && Attributes & FILE_ATTRIBUTE_DIRECTORY)
|
if (Attributes != INVALID_FILE_ATTRIBUTES && Attributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
return true;
|
return true;
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (!Recursive)
|
||||||
|
{
|
||||||
|
Error::SetWin32(error, "CreateDirectoryW() failed: ", lastError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (lastError == ERROR_PATH_NOT_FOUND)
|
|
||||||
|
// check error
|
||||||
|
if (lastError == ERROR_PATH_NOT_FOUND)
|
||||||
{
|
{
|
||||||
// part of the path does not exist, so we'll create the parent folders, then
|
// part of the path does not exist, so we'll create the parent folders, then
|
||||||
// the full path again.
|
// the full path again.
|
||||||
|
@ -1693,10 +1698,13 @@ bool FileSystem::CreateDirectory(const char* Path, bool Recursive)
|
||||||
{
|
{
|
||||||
lastError = GetLastError();
|
lastError = GetLastError();
|
||||||
if (lastError != ERROR_ALREADY_EXISTS) // fine, continue to next path segment
|
if (lastError != ERROR_ALREADY_EXISTS) // fine, continue to next path segment
|
||||||
|
{
|
||||||
|
Error::SetWin32(error, "CreateDirectoryW() failed: ", lastError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// re-create the end if it's not a separator, check / as well because windows can interpret them
|
// re-create the end if it's not a separator, check / as well because windows can interpret them
|
||||||
if (Path[pathLength - 1] != '\\' && Path[pathLength - 1] != '/')
|
if (Path[pathLength - 1] != '\\' && Path[pathLength - 1] != '/')
|
||||||
|
@ -1706,9 +1714,12 @@ bool FileSystem::CreateDirectory(const char* Path, bool Recursive)
|
||||||
{
|
{
|
||||||
lastError = GetLastError();
|
lastError = GetLastError();
|
||||||
if (lastError != ERROR_ALREADY_EXISTS)
|
if (lastError != ERROR_ALREADY_EXISTS)
|
||||||
|
{
|
||||||
|
Error::SetWin32(error, "CreateDirectoryW() failed: ", lastError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ok
|
// ok
|
||||||
return true;
|
return true;
|
||||||
|
@ -1716,6 +1727,7 @@ bool FileSystem::CreateDirectory(const char* Path, bool Recursive)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// unhandled error
|
// unhandled error
|
||||||
|
Error::SetWin32(error, "CreateDirectoryW() failed: ", lastError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1733,14 +1745,16 @@ bool FileSystem::DeleteFile(const char* path)
|
||||||
return (DeleteFileW(wpath.c_str()) == TRUE);
|
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 old_wpath = GetWin32Path(old_path);
|
||||||
const std::wstring new_wpath = GetWin32Path(new_path);
|
const std::wstring new_wpath = GetWin32Path(new_path);
|
||||||
|
|
||||||
if (!MoveFileExW(old_wpath.c_str(), new_wpath.c_str(), MOVEFILE_REPLACE_EXISTING))
|
if (!MoveFileExW(old_wpath.c_str(), new_wpath.c_str(), MOVEFILE_REPLACE_EXISTING))
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("MoveFileEx('%s', '%s') failed: %08X", old_path, new_path, GetLastError());
|
const DWORD err = GetLastError();
|
||||||
|
Error::SetWin32(error, "MoveFileExW() failed: ", err);
|
||||||
|
Log_ErrorPrintf("MoveFileEx('%s', '%s') failed: %08X", old_path, new_path, err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2145,7 +2159,7 @@ bool FileSystem::DirectoryIsEmpty(const char* path)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystem::CreateDirectory(const char* path, bool recursive)
|
bool FileSystem::CreateDirectory(const char* path, bool recursive, Error* error)
|
||||||
{
|
{
|
||||||
// has a path
|
// has a path
|
||||||
const size_t pathLength = std::strlen(path);
|
const size_t pathLength = std::strlen(path);
|
||||||
|
@ -2156,9 +2170,6 @@ bool FileSystem::CreateDirectory(const char* path, bool recursive)
|
||||||
if (mkdir(path, 0777) == 0)
|
if (mkdir(path, 0777) == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!recursive)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// check error
|
// check error
|
||||||
int lastError = errno;
|
int lastError = errno;
|
||||||
if (lastError == EEXIST)
|
if (lastError == EEXIST)
|
||||||
|
@ -2167,9 +2178,14 @@ bool FileSystem::CreateDirectory(const char* path, bool recursive)
|
||||||
struct stat sysStatData;
|
struct stat sysStatData;
|
||||||
if (stat(path, &sysStatData) == 0 && S_ISDIR(sysStatData.st_mode))
|
if (stat(path, &sysStatData) == 0 && S_ISDIR(sysStatData.st_mode))
|
||||||
return true;
|
return true;
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (!recursive)
|
||||||
|
{
|
||||||
|
Error::SetErrno(error, "mkdir() failed: ", lastError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (lastError == ENOENT)
|
else if (lastError == ENOENT)
|
||||||
{
|
{
|
||||||
// part of the path does not exist, so we'll create the parent folders, then
|
// part of the path does not exist, so we'll create the parent folders, then
|
||||||
|
@ -2186,9 +2202,12 @@ bool FileSystem::CreateDirectory(const char* path, bool recursive)
|
||||||
{
|
{
|
||||||
lastError = errno;
|
lastError = errno;
|
||||||
if (lastError != EEXIST) // fine, continue to next path segment
|
if (lastError != EEXIST) // fine, continue to next path segment
|
||||||
|
{
|
||||||
|
Error::SetErrno(error, "mkdir() failed: ", lastError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tempPath.push_back(path[i]);
|
tempPath.push_back(path[i]);
|
||||||
}
|
}
|
||||||
|
@ -2200,9 +2219,12 @@ bool FileSystem::CreateDirectory(const char* path, bool recursive)
|
||||||
{
|
{
|
||||||
lastError = errno;
|
lastError = errno;
|
||||||
if (lastError != EEXIST)
|
if (lastError != EEXIST)
|
||||||
|
{
|
||||||
|
Error::SetErrno(error, "mkdir() failed: ", lastError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ok
|
// ok
|
||||||
return true;
|
return true;
|
||||||
|
@ -2210,6 +2232,7 @@ bool FileSystem::CreateDirectory(const char* path, bool recursive)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// unhandled error
|
// unhandled error
|
||||||
|
Error::SetErrno(error, "mkdir() failed: ", lastError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2226,14 +2249,19 @@ bool FileSystem::DeleteFile(const char* path)
|
||||||
return (unlink(path) == 0);
|
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')
|
if (old_path[0] == '\0' || new_path[0] == '\0')
|
||||||
|
{
|
||||||
|
Error::SetStringView(error, "Path is empty.");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (rename(old_path, new_path) != 0)
|
if (rename(old_path, new_path) != 0)
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("rename('%s', '%s') failed: %d", old_path, new_path, errno);
|
const int err = errno;
|
||||||
|
Error::SetErrno(error, "rename() failed: ", err);
|
||||||
|
Log_ErrorPrintf("rename('%s', '%s') failed: %d", old_path, new_path, err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ bool DirectoryIsEmpty(const char* path);
|
||||||
bool DeleteFile(const char* path);
|
bool DeleteFile(const char* path);
|
||||||
|
|
||||||
/// Rename file
|
/// 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
|
/// Deleter functor for managed file pointers
|
||||||
struct FileDeleter
|
struct FileDeleter
|
||||||
|
@ -151,11 +151,11 @@ bool WriteStringToFile(const char* filename, const std::string_view& sv);
|
||||||
/// if the directory already exists, the return value will be true.
|
/// if the directory already exists, the return value will be true.
|
||||||
/// if Recursive is specified, all parent directories will be created
|
/// if Recursive is specified, all parent directories will be created
|
||||||
/// if they do not exist.
|
/// if they do not exist.
|
||||||
bool CreateDirectory(const char* path, bool recursive);
|
bool CreateDirectory(const char* path, bool recursive, Error* error = nullptr);
|
||||||
|
|
||||||
/// Creates a directory if it doesn't already exist.
|
/// Creates a directory if it doesn't already exist.
|
||||||
/// Returns false if it does not exist and creation failed.
|
/// 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.
|
/// Removes a directory.
|
||||||
bool DeleteDirectory(const char* path);
|
bool DeleteDirectory(const char* path);
|
||||||
|
|
Loading…
Reference in a new issue