From 5c9ba6ccbb8150cb89edf2d708e841c3d9816206 Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Thu, 31 Jul 2025 20:50:38 -0500 Subject: [PATCH 1/8] Swap write access mode for read write Opening with access mode w will erase the opened file. We do not want this. --- src/common/io_file.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/io_file.cpp b/src/common/io_file.cpp index 6fa9062a75c..c5fbd8700a5 100644 --- a/src/common/io_file.cpp +++ b/src/common/io_file.cpp @@ -41,7 +41,7 @@ namespace { case FileAccessMode::Read: return L"rb"; case FileAccessMode::Write: - return L"wb"; + return L"r+b"; case FileAccessMode::Append: return L"ab"; case FileAccessMode::ReadWrite: @@ -55,7 +55,7 @@ namespace { case FileAccessMode::Read: return L"r"; case FileAccessMode::Write: - return L"w"; + return L"r+"; case FileAccessMode::Append: return L"a"; case FileAccessMode::ReadWrite: @@ -92,7 +92,7 @@ namespace { case FileAccessMode::Read: return "rb"; case FileAccessMode::Write: - return "wb"; + return "r+b"; case FileAccessMode::Append: return "ab"; case FileAccessMode::ReadWrite: @@ -106,7 +106,7 @@ namespace { case FileAccessMode::Read: return "r"; case FileAccessMode::Write: - return "w"; + return "r+"; case FileAccessMode::Append: return "a"; case FileAccessMode::ReadWrite: From 12dc10363548fec24092a640f9edff3ab30c5d22 Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Thu, 31 Jul 2025 21:04:41 -0500 Subject: [PATCH 2/8] Create mode Opening with write access was previously the only way to create a file through open, so add a separate FileAccessMode that uses the write access mode to create files. --- src/common/io_file.cpp | 20 ++++++++++++-------- src/common/io_file.h | 11 ++++++++--- src/core/libraries/kernel/file_system.cpp | 2 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/common/io_file.cpp b/src/common/io_file.cpp index c5fbd8700a5..249d0e0f476 100644 --- a/src/common/io_file.cpp +++ b/src/common/io_file.cpp @@ -40,28 +40,30 @@ namespace { switch (mode) { case FileAccessMode::Read: return L"rb"; - case FileAccessMode::Write: - return L"r+b"; case FileAccessMode::Append: return L"ab"; + case FileAccessMode::Write: case FileAccessMode::ReadWrite: return L"r+b"; case FileAccessMode::ReadAppend: return L"a+b"; + case FileAccessMode::Create: + return L"wb"; } break; case FileType::TextFile: switch (mode) { case FileAccessMode::Read: return L"r"; - case FileAccessMode::Write: - return L"r+"; case FileAccessMode::Append: return L"a"; + case FileAccessMode::Write: case FileAccessMode::ReadWrite: return L"r+"; case FileAccessMode::ReadAppend: return L"a+"; + case FileAccessMode::Create: + return L"w"; } break; } @@ -91,28 +93,30 @@ namespace { switch (mode) { case FileAccessMode::Read: return "rb"; - case FileAccessMode::Write: - return "r+b"; case FileAccessMode::Append: return "ab"; + case FileAccessMode::Write: case FileAccessMode::ReadWrite: return "r+b"; case FileAccessMode::ReadAppend: return "a+b"; + case FileAccessMode::Create: + return "wb"; } break; case FileType::TextFile: switch (mode) { case FileAccessMode::Read: return "r"; - case FileAccessMode::Write: - return "r+"; case FileAccessMode::Append: return "a"; + case FileAccessMode::Write: case FileAccessMode::ReadWrite: return "r+"; case FileAccessMode::ReadAppend: return "a+"; + case FileAccessMode::Create: + return "w"; } break; } diff --git a/src/common/io_file.h b/src/common/io_file.h index cb01e154afa..b2ff14af197 100644 --- a/src/common/io_file.h +++ b/src/common/io_file.h @@ -21,9 +21,8 @@ enum class FileAccessMode { */ Read = 1 << 0, /** - * If the file at path exists, the existing contents of the file are erased. - * The empty file is then opened for writing. - * If the file at path does not exist, it creates and opens a new empty file for writing. + * If the file at path exists, it opens the file for reading and writing. + * If the file at path does not exist, it fails to open the file. */ Write = 1 << 1, /** @@ -42,6 +41,12 @@ enum class FileAccessMode { * reading and appending. */ ReadAppend = Read | Append, + /** + * If the file at path exists, the existing contents of the file are erased. + * The empty file is then opened for writing. + * If the file at path does not exist, it creates and opens a new empty file for writing. + */ + Create = 1 << 3, }; DECLARE_ENUM_FLAG_OPERATORS(FileAccessMode); diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 17520211d2a..8546dac4945 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -127,7 +127,7 @@ s32 PS4_SYSV_ABI open(const char* raw_path, s32 flags, u16 mode) { return -1; } // Create a file if it doesn't exist - Common::FS::IOFile out(file->m_host_name, Common::FS::FileAccessMode::Write); + Common::FS::IOFile out(file->m_host_name, Common::FS::FileAccessMode::Create); } } else if (!exists) { // If we're not creating a file, and it doesn't exist, return ENOENT From 038ad7d782a0e99898aa44aef393a1c25b78c267 Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Thu, 31 Jul 2025 21:04:53 -0500 Subject: [PATCH 3/8] Update file_system.cpp Remove a hack added to posix_rename to bypass the file clearing behaviors of FileAccessMode::Write --- src/core/libraries/kernel/file_system.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 8546dac4945..47ccc3dde62 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -784,11 +784,7 @@ s32 PS4_SYSV_ABI posix_rename(const char* from, const char* to) { auto* h = Common::Singleton::Instance(); auto file = h->GetFile(src_path); if (file) { - // We need to force ReadWrite if the file had Write access before - // Otherwise f.Open will clear the file contents. - auto access_mode = file->f.GetAccessMode() == Common::FS::FileAccessMode::Write - ? Common::FS::FileAccessMode::ReadWrite - : file->f.GetAccessMode(); + auto access_mode = file->f.GetAccessMode(); file->f.Close(); std::filesystem::remove(src_path); file->f.Open(dst_path, access_mode); From a53877062a4d838b729eef0a0d88dc73674bd1fc Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Thu, 31 Jul 2025 21:30:27 -0500 Subject: [PATCH 4/8] Check access mode in read functions Write-only files cause the EBADF return on the various read functions. Now that we're opening files differently, properly handling this is necessary. --- src/core/libraries/kernel/file_system.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 47ccc3dde62..d086459450d 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -334,7 +334,7 @@ size_t ReadFile(Common::FS::IOFile& file, void* buf, size_t nbytes) { size_t PS4_SYSV_ABI readv(s32 fd, const SceKernelIovec* iov, s32 iovcnt) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(fd); - if (file == nullptr) { + if (file == nullptr || file->f.GetAccessMode() == Common::FS::FileAccessMode::Write) { *__Error() = POSIX_EBADF; return -1; } @@ -472,7 +472,7 @@ s64 PS4_SYSV_ABI sceKernelLseek(s32 fd, s64 offset, s32 whence) { s64 PS4_SYSV_ABI read(s32 fd, void* buf, size_t nbytes) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(fd); - if (file == nullptr) { + if (file == nullptr || file->f.GetAccessMode() == Common::FS::FileAccessMode::Write) { *__Error() = POSIX_EBADF; return -1; } @@ -812,7 +812,7 @@ s64 PS4_SYSV_ABI posix_preadv(s32 fd, SceKernelIovec* iov, s32 iovcnt, s64 offse auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(fd); - if (file == nullptr) { + if (file == nullptr || file->f.GetAccessMode() == Common::FS::FileAccessMode::Write) { *__Error() = POSIX_EBADF; return -1; } From ad5c019c6acb685cd984279481418ea3899468c6 Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Thu, 31 Jul 2025 21:48:22 -0500 Subject: [PATCH 5/8] Separate appends into proper modes Fixes a potential regression from one of my prior PRs, and ensures the Write | Append flag combo also behaves properly in read-related functions. --- src/common/io_file.h | 7 +++++- src/core/libraries/kernel/file_system.cpp | 28 +++++++++++++++-------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/common/io_file.h b/src/common/io_file.h index b2ff14af197..b59ae113bf0 100644 --- a/src/common/io_file.h +++ b/src/common/io_file.h @@ -21,7 +21,7 @@ enum class FileAccessMode { */ Read = 1 << 0, /** - * If the file at path exists, it opens the file for reading and writing. + * If the file at path exists, it opens the file for writing. * If the file at path does not exist, it fails to open the file. */ Write = 1 << 1, @@ -107,6 +107,11 @@ class IOFile final { return file != nullptr; } + bool IsWriteOnly() const { + return file_access_mode == FileAccessMode::Append || + file_access_mode == FileAccessMode::Write; + } + uintptr_t GetFileMapping(); int Open(const std::filesystem::path& path, FileAccessMode mode, diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index d086459450d..06392c4c86e 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -202,22 +202,30 @@ s32 PS4_SYSV_ABI open(const char* raw_path, s32 flags, u16 mode) { } if (read) { - // Read only + // Open exclusively for reading e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Read); } else if (read_only) { // Can't open files with write/read-write access in a read only directory h->DeleteHandle(handle); *__Error() = POSIX_EROFS; return -1; - } else if (append) { - // Append can be specified with rdwr or write, but we treat it as a separate mode. - e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Append); } else if (write) { - // Write only - e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Write); + if (append) { + // Open exclusively for appending + e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Append); + } else { + // Open exclusively for writing + e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Write); + } } else if (rdwr) { // Read and write - e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::ReadWrite); + if (append) { + // Open for reading and appending + e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::ReadAppend); + } else { + // Open for reading and writing + e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::ReadWrite); + } } } @@ -334,7 +342,7 @@ size_t ReadFile(Common::FS::IOFile& file, void* buf, size_t nbytes) { size_t PS4_SYSV_ABI readv(s32 fd, const SceKernelIovec* iov, s32 iovcnt) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(fd); - if (file == nullptr || file->f.GetAccessMode() == Common::FS::FileAccessMode::Write) { + if (file == nullptr || file->f.IsWriteOnly()) { *__Error() = POSIX_EBADF; return -1; } @@ -472,7 +480,7 @@ s64 PS4_SYSV_ABI sceKernelLseek(s32 fd, s64 offset, s32 whence) { s64 PS4_SYSV_ABI read(s32 fd, void* buf, size_t nbytes) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(fd); - if (file == nullptr || file->f.GetAccessMode() == Common::FS::FileAccessMode::Write) { + if (file == nullptr || file->f.IsWriteOnly()) { *__Error() = POSIX_EBADF; return -1; } @@ -812,7 +820,7 @@ s64 PS4_SYSV_ABI posix_preadv(s32 fd, SceKernelIovec* iov, s32 iovcnt, s64 offse auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(fd); - if (file == nullptr || file->f.GetAccessMode() == Common::FS::FileAccessMode::Write) { + if (file == nullptr || file->f.IsWriteOnly()) { *__Error() = POSIX_EBADF; return -1; } From b0f93af18caac4e9c464da90aa11afb5de916fdf Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Thu, 31 Jul 2025 21:55:42 -0500 Subject: [PATCH 6/8] Move IsWriteOnly check after device/socket reads file->f is only valid for files, so checking this before checking for sockets/devices will cause access violations. --- src/core/libraries/kernel/file_system.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 06392c4c86e..2a4e99a0f38 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -342,7 +342,7 @@ size_t ReadFile(Common::FS::IOFile& file, void* buf, size_t nbytes) { size_t PS4_SYSV_ABI readv(s32 fd, const SceKernelIovec* iov, s32 iovcnt) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(fd); - if (file == nullptr || file->f.IsWriteOnly()) { + if (file == nullptr) { *__Error() = POSIX_EBADF; return -1; } @@ -356,6 +356,12 @@ size_t PS4_SYSV_ABI readv(s32 fd, const SceKernelIovec* iov, s32 iovcnt) { } return result; } + + if (file->f.IsWriteOnly()) { + *__Error() = POSIX_EBADF; + return -1; + } + size_t total_read = 0; for (s32 i = 0; i < iovcnt; i++) { total_read += ReadFile(file->f, iov[i].iov_base, iov[i].iov_len); @@ -480,7 +486,7 @@ s64 PS4_SYSV_ABI sceKernelLseek(s32 fd, s64 offset, s32 whence) { s64 PS4_SYSV_ABI read(s32 fd, void* buf, size_t nbytes) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(fd); - if (file == nullptr || file->f.IsWriteOnly()) { + if (file == nullptr) { *__Error() = POSIX_EBADF; return -1; } @@ -501,6 +507,12 @@ s64 PS4_SYSV_ABI read(s32 fd, void* buf, size_t nbytes) { } return result; } + + if (file->f.IsWriteOnly()) { + *__Error() = POSIX_EBADF; + return -1; + } + return ReadFile(file->f, buf, nbytes); } @@ -820,7 +832,7 @@ s64 PS4_SYSV_ABI posix_preadv(s32 fd, SceKernelIovec* iov, s32 iovcnt, s64 offse auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(fd); - if (file == nullptr || file->f.IsWriteOnly()) { + if (file == nullptr) { *__Error() = POSIX_EBADF; return -1; } @@ -835,6 +847,11 @@ s64 PS4_SYSV_ABI posix_preadv(s32 fd, SceKernelIovec* iov, s32 iovcnt, s64 offse return result; } + if (file->f.IsWriteOnly()) { + *__Error() = POSIX_EBADF; + return -1; + } + const s64 pos = file->f.Tell(); SCOPE_EXIT { file->f.Seek(pos); From bc7af55a5f0a47e20213eaec49a506bf2d7b649c Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Thu, 31 Jul 2025 22:26:32 -0500 Subject: [PATCH 7/8] Fix issues Now that Write is identical to ReadWrite, internal uses of Write need to be swapped to my new Create mode --- src/core/devtools/widget/common.h | 2 +- src/core/devtools/widget/frame_dump.cpp | 2 +- src/core/file_format/psf.cpp | 2 +- src/core/libraries/save_data/save_instance.cpp | 2 +- src/core/libraries/save_data/save_memory.cpp | 4 ++-- src/core/libraries/save_data/savedata.cpp | 2 +- src/core/loader/elf.cpp | 8 ++++---- src/core/loader/symbols_resolver.cpp | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/core/devtools/widget/common.h b/src/core/devtools/widget/common.h index 4684f6e3b26..1c79ffcacd0 100644 --- a/src/core/devtools/widget/common.h +++ b/src/core/devtools/widget/common.h @@ -152,7 +152,7 @@ inline std::string RunDisassembler(const std::string& disassembler_cli, const T& } } else { cli.replace(pos, src_arg.size(), "\"" + bin_path.string() + "\""); - Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Write); + Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Create); file.Write(shader_code); file.Close(); diff --git a/src/core/devtools/widget/frame_dump.cpp b/src/core/devtools/widget/frame_dump.cpp index 2445bdcb5ff..6f3b7eb4d9f 100644 --- a/src/core/devtools/widget/frame_dump.cpp +++ b/src/core/devtools/widget/frame_dump.cpp @@ -122,7 +122,7 @@ void FrameDumpViewer::Draw() { const auto fname = fmt::format("{:%F %H-%M-%S} {}_{}_{}.bin", now_time, magic_enum::enum_name(selected_queue_type), selected_submit_num, selected_queue_num2); - Common::FS::IOFile file(fname, Common::FS::FileAccessMode::Write); + Common::FS::IOFile file(fname, Common::FS::FileAccessMode::Create); const auto& data = frame_dump->queues[selected_cmd].data; if (file.IsOpen()) { DebugState.ShowDebugMessage(fmt::format("Dumping cmd as {}", fname)); diff --git a/src/core/file_format/psf.cpp b/src/core/file_format/psf.cpp index 7e0ffc9a3ce..04782833075 100644 --- a/src/core/file_format/psf.cpp +++ b/src/core/file_format/psf.cpp @@ -99,7 +99,7 @@ bool PSF::Open(const std::vector& psf_buffer) { } bool PSF::Encode(const std::filesystem::path& filepath) const { - Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Write); + Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Create); if (!file.IsOpen()) { return false; } diff --git a/src/core/libraries/save_data/save_instance.cpp b/src/core/libraries/save_data/save_instance.cpp index 05253eb23f8..75a644fdbcc 100644 --- a/src/core/libraries/save_data/save_instance.cpp +++ b/src/core/libraries/save_data/save_instance.cpp @@ -180,7 +180,7 @@ void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_cor } if (!ignore_corrupt && !read_only) { - Common::FS::IOFile f(corrupt_file_path, Common::FS::FileAccessMode::Write); + Common::FS::IOFile f(corrupt_file_path, Common::FS::FileAccessMode::Create); f.Close(); } diff --git a/src/core/libraries/save_data/save_memory.cpp b/src/core/libraries/save_data/save_memory.cpp index ab3ce2d4f0e..fb251148074 100644 --- a/src/core/libraries/save_data/save_memory.cpp +++ b/src/core/libraries/save_data/save_memory.cpp @@ -59,7 +59,7 @@ void PersistMemory(u32 slot_id, bool lock) { while (n++ < 10) { try { IOFile f; - int r = f.Open(memoryPath, Common::FS::FileAccessMode::Write); + int r = f.Open(memoryPath, Common::FS::FileAccessMode::Create); if (f.IsOpen()) { f.WriteRaw(data.memory_cache.data(), data.memory_cache.size()); f.Close(); @@ -148,7 +148,7 @@ void SetIcon(u32 slot_id, void* buf, size_t buf_size) { fs::copy_file(src_icon, icon_path); } } else { - IOFile file(icon_path, Common::FS::FileAccessMode::Write); + IOFile file(icon_path, Common::FS::FileAccessMode::Create); file.WriteRaw(buf, buf_size); file.Close(); } diff --git a/src/core/libraries/save_data/savedata.cpp b/src/core/libraries/save_data/savedata.cpp index 62426d46156..0f21499be9e 100644 --- a/src/core/libraries/save_data/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -1389,7 +1389,7 @@ Error PS4_SYSV_ABI sceSaveDataSaveIcon(const OrbisSaveDataMountPoint* mountPoint } try { - const Common::FS::IOFile file(path, Common::FS::FileAccessMode::Write); + const Common::FS::IOFile file(path, Common::FS::FileAccessMode::Create); file.WriteRaw(icon->buf, std::min(icon->bufSize, icon->dataSize)); } catch (const fs::filesystem_error& e) { LOG_ERROR(Lib_SaveData, "Failed to load icon: {}", e.what()); diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 4de20436f9d..ed3f43c1c35 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -502,19 +502,19 @@ bool Elf::IsSharedLib() { } void Elf::ElfHeaderDebugDump(const std::filesystem::path& file_name) { - Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Write, + Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Create, Common::FS::FileType::TextFile}; f.WriteString(ElfHeaderStr()); } void Elf::SelfHeaderDebugDump(const std::filesystem::path& file_name) { - Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Write, + Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Create, Common::FS::FileType::TextFile}; f.WriteString(SElfHeaderStr()); } void Elf::SelfSegHeaderDebugDump(const std::filesystem::path& file_name) { - Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Write, + Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Create, Common::FS::FileType::TextFile}; for (u16 i = 0; i < m_self.segment_count; i++) { f.WriteString(SELFSegHeader(i)); @@ -522,7 +522,7 @@ void Elf::SelfSegHeaderDebugDump(const std::filesystem::path& file_name) { } void Elf::PHeaderDebugDump(const std::filesystem::path& file_name) { - Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Write, + Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Create, Common::FS::FileType::TextFile}; if (m_elf_header.e_phentsize > 0) { for (u16 i = 0; i < m_elf_header.e_phnum; i++) { diff --git a/src/core/loader/symbols_resolver.cpp b/src/core/loader/symbols_resolver.cpp index 0b09a0201d3..a24d2985ba4 100644 --- a/src/core/loader/symbols_resolver.cpp +++ b/src/core/loader/symbols_resolver.cpp @@ -32,7 +32,7 @@ const SymbolRecord* SymbolsResolver::FindSymbol(const SymbolResolver& s) const { } void SymbolsResolver::DebugDump(const std::filesystem::path& file_name) { - Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Write, + Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Create, Common::FS::FileType::TextFile}; for (const auto& symbol : m_symbols) { const auto ids = Common::SplitString(symbol.name, '#'); From f20636aee569dfc843375d716e947b72f19eb56d Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Sat, 2 Aug 2025 17:00:56 -0500 Subject: [PATCH 8/8] Fix remaining uses of FileAccessMode write to create files Missed these before. --- src/common/io_file.h | 2 +- src/common/logging/backend.cpp | 2 +- src/shader_recompiler/frontend/translate/translate.cpp | 2 +- .../ir/passes/flatten_extended_userdata_pass.cpp | 2 +- src/shader_recompiler/ir/program.cpp | 4 ++-- src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/common/io_file.h b/src/common/io_file.h index b59ae113bf0..23cfbe2bef0 100644 --- a/src/common/io_file.h +++ b/src/common/io_file.h @@ -220,7 +220,7 @@ class IOFile final { } static size_t WriteBytes(const std::filesystem::path path, const auto& data) { - IOFile out(path, FileAccessMode::Write); + IOFile out(path, FileAccessMode::Create); return out.Write(data); } diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index c16a5399aa3..045acd0614d 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -62,7 +62,7 @@ class ColorConsoleBackend { class FileBackend { public: explicit FileBackend(const std::filesystem::path& filename) - : file{filename, FS::FileAccessMode::Write, FS::FileType::TextFile} {} + : file{filename, FS::FileAccessMode::Create, FS::FileType::TextFile} {} ~FileBackend() = default; diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index ad6cf5f12d2..ae87a8679e1 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -544,7 +544,7 @@ void Translator::EmitFetch(const GcnInst& inst) { std::filesystem::create_directories(dump_dir); } const auto filename = fmt::format("vs_{:#018x}.fetch.bin", info.pgm_hash); - const auto file = IOFile{dump_dir / filename, FileAccessMode::Write}; + const auto file = IOFile{dump_dir / filename, FileAccessMode::Create}; file.WriteRaw(fetch_data->code, fetch_data->size); } diff --git a/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp b/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp index e0c99655d81..760a22cd8a4 100644 --- a/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp +++ b/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp @@ -39,7 +39,7 @@ static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t code std::filesystem::create_directories(dump_dir); } const auto filename = fmt::format("{}_{:#018x}.srtprogram.txt", info.stage, info.pgm_hash); - const auto file = IOFile{dump_dir / filename, FileAccessMode::Write, FileType::TextFile}; + const auto file = IOFile{dump_dir / filename, FileAccessMode::Create, FileType::TextFile}; u64 address = reinterpret_cast(code); u64 code_end = address + codesize; diff --git a/src/shader_recompiler/ir/program.cpp b/src/shader_recompiler/ir/program.cpp index f2f6e34fa14..1d03ea9abcf 100644 --- a/src/shader_recompiler/ir/program.cpp +++ b/src/shader_recompiler/ir/program.cpp @@ -28,7 +28,7 @@ void DumpProgram(const Program& program, const Info& info, const std::string& ty } const auto ir_filename = fmt::format("{}_{:#018x}.{}irprogram.txt", info.stage, info.pgm_hash, type); - const auto ir_file = IOFile{dump_dir / ir_filename, FileAccessMode::Write, FileType::TextFile}; + const auto ir_file = IOFile{dump_dir / ir_filename, FileAccessMode::Create, FileType::TextFile}; size_t index{0}; std::map inst_to_index; @@ -46,7 +46,7 @@ void DumpProgram(const Program& program, const Info& info, const std::string& ty const auto asl_filename = fmt::format("{}_{:#018x}.{}asl.txt", info.stage, info.pgm_hash, type); const auto asl_file = - IOFile{dump_dir / asl_filename, FileAccessMode::Write, FileType::TextFile}; + IOFile{dump_dir / asl_filename, FileAccessMode::Create, FileType::TextFile}; for (const auto& node : program.syntax_list) { std::string s = IR::DumpASLNode(node, block_to_index, inst_to_index) + '\n'; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index bce16cbff27..ac963f8c67e 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -611,7 +611,7 @@ void PipelineCache::DumpShader(std::span code, u64 hash, Shader::Stag std::filesystem::create_directories(dump_dir); } const auto filename = fmt::format("{}.{}", GetShaderName(stage, hash, perm_idx), ext); - const auto file = IOFile{dump_dir / filename, FileAccessMode::Write}; + const auto file = IOFile{dump_dir / filename, FileAccessMode::Create}; file.WriteSpan(code); }