From 01d16fdfd1abd79429b7544cf45a35bc8258d30a Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Sat, 20 May 2023 02:32:36 +0300 Subject: [PATCH] [FS] Better DeleteFile, fclose when file session is closed --- src/core/fs/archive_ext_save_data.cpp | 19 ++++++++++++++++-- src/core/fs/archive_save_data.cpp | 29 ++++++++++++++++++++++++++- src/core/kernel/file_operations.cpp | 7 ++++++- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/core/fs/archive_ext_save_data.cpp b/src/core/fs/archive_ext_save_data.cpp index 51b89aca..788fd251 100644 --- a/src/core/fs/archive_ext_save_data.cpp +++ b/src/core/fs/archive_ext_save_data.cpp @@ -38,12 +38,27 @@ FSResult ExtSaveDataArchive::deleteFile(const FSPath& path) { fs::path p = IOFile::getAppData() / backingFolder; p += fs::path(path.utf16_string).make_preferred(); + if (fs::is_directory(p)) { + Helpers::panic("ExtSaveData::DeleteFile: Tried to delete directory"); + } + + if (!fs::is_regular_file(p)) { + return FSResult::FileNotFound; + } + std::error_code ec; bool success = fs::remove(p, ec); - return success ? FSResult::Success : FSResult::FileNotFound; + + // It might still be possible for fs::remove to fail, if there's eg an open handle to a file being deleted + // In this case, print a warning, but still return success for now + if (!success) { + Helpers::warn("ExtSaveData::DeleteFile: fs::remove failed\n"); + } + + return FSResult::Success; } - Helpers::panic("ExtSaveDataArchive::DeleteFile: Failed"); + Helpers::panic("ExtSaveDataArchive::DeleteFile: Unknown path type"); return FSResult::Success; } diff --git a/src/core/fs/archive_save_data.cpp b/src/core/fs/archive_save_data.cpp index a25ba08f..57d2f2fb 100644 --- a/src/core/fs/archive_save_data.cpp +++ b/src/core/fs/archive_save_data.cpp @@ -31,7 +31,34 @@ FSResult SaveDataArchive::createDirectory(const FSPath& path) { } FSResult SaveDataArchive::deleteFile(const FSPath& path) { - Helpers::panic("[SaveData] Unimplemented DeleteFile"); + if (path.type == PathType::UTF16) { + if (!isPathSafe(path)) + Helpers::panic("Unsafe path in SaveData::DeleteFile"); + + fs::path p = IOFile::getAppData() / "SaveData"; + p += fs::path(path.utf16_string).make_preferred(); + + if (fs::is_directory(p)) { + Helpers::panic("SaveData::DeleteFile: Tried to delete directory"); + } + + if (!fs::is_regular_file(p)) { + return FSResult::FileNotFound; + } + + std::error_code ec; + bool success = fs::remove(p, ec); + + // It might still be possible for fs::remove to fail, if there's eg an open handle to a file being deleted + // In this case, print a warning, but still return success for now + if (!success) { + Helpers::warn("SaveData::DeleteFile: fs::remove failed\n"); + } + + return FSResult::Success; + } + + Helpers::panic("SaveDataArchive::DeleteFile: Unknown path type"); return FSResult::Success; } diff --git a/src/core/kernel/file_operations.cpp b/src/core/kernel/file_operations.cpp index 84b77837..331a3bd5 100644 --- a/src/core/kernel/file_operations.cpp +++ b/src/core/kernel/file_operations.cpp @@ -41,7 +41,12 @@ void Kernel::closeFile(u32 messagePointer, Handle fileHandle) { Helpers::panic("Called CloseFile on non-existent file"); } - p->getData()->isOpen = false; + FileSession* session = p->getData(); + session->isOpen = false; + if (session->fd != nullptr) { + fclose(session->fd); + } + mem.write32(messagePointer + 4, Result::Success); }