From 0e6614cf19dc3e45e19d6b1026c328bff33b74e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 3 Sep 2026 13:35:48 -0600 Subject: [PATCH] Report PSP file attributes rather than the host's DirectoryFileSystem passed the host's permission bits and directory size straight through to the game. The PSP has neither - its FAT driver makes a mode up from the entry type and whether it's writable, and reports no size for a directory. So a game saw 0644/0755 and a 4096 byte directory on Linux, but 0664/0777 and 0 on Windows, where the file layer already synthesizes those bits. Now both platforms report what the PSP does: 0777 for directories, 0664 for writable files, 0444 for read-only ones, and no size on a directory. The parent ".." entry keeps its 4096, which is what the hardware reports for that one. Also fixes the synthetic PSP directory entry using 0x777 where 0777 was meant. Fixes io/directory/directory, moved to tests_good. Co-Authored-By: Claude Opus 5 (1M context) --- AGENTS.md | 13 ++++++++++++- Core/FileSystems/DirectoryFileSystem.cpp | 20 +++++++++++++++++--- test.py | 2 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 9506fb27ee..b9b43b7afd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -214,6 +214,14 @@ Keep commit messages focused, not overly long (although sometimes it's motivated is super complex). Do not report things like 100/100 tests passed - that's a given, if tests break you aren't supposed to make a commit. +Omit the session marker. + +## Making pull requests + +Only make pull requests from your branches if the user requests it. + +Prefix your PR messages with this: "### Claude says". Also omit the session marker. + ## Code style 4-wide tabs, not spaces. @@ -232,10 +240,13 @@ Style example: class MyClass { public: MyClass(int memberVar) : memberVar_(memberVar) {} - int MemberFunc(); + int MemberFunc() const { + int localVar = 0; + } private: int memberVar_; + int initializedMemberVar_ = 0; } ``` diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index b9f91f55a3..0b64b8574e 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -749,6 +749,17 @@ size_t DirectoryFileSystem::SeekFile(u32 handle, s32 position, FileMove type) { } } +// The PSP has no host permission bits to report. Its FAT driver makes a mode up from the entry +// type and whether it can be written, so a file that happens to be 0644 on the host still looks +// like 0664 to the game, and a 0755 directory looks like 0777. Passing the host's bits through +// meant games saw different modes on Windows and Linux - see io/directory and io/file. +static u32 PspAccessBits(bool isDirectory, bool isWritable) { + if (isDirectory) { + return 0777; + } + return isWritable ? 0664 : 0444; +} + PSPFileInfo DirectoryFileSystem::GetFileInfo(std::string filename) { PSPFileInfo x; x.name = filename; @@ -774,7 +785,7 @@ PSPFileInfo DirectoryFileSystem::GetFileInfo(std::string filename) { if (x.type != FILETYPE_DIRECTORY) { x.size = info.size; } - x.access = info.access; + x.access = PspAccessBits(info.isDirectory, info.isWritable); time_t atime = info.atime; time_t ctime = info.ctime; time_t mtime = info.mtime; @@ -934,7 +945,10 @@ std::vector DirectoryFileSystem::GetDirListing(std::string_view pat } } if (file.name == "..") { + // The PSP reports a size for the parent entry, but not for directories in general. entry.size = 4096; + } else if (file.isDirectory) { + entry.size = 0; } else { entry.size = file.size; } @@ -943,7 +957,7 @@ std::vector DirectoryFileSystem::GetDirListing(std::string_view pat } else { entry.type = FILETYPE_NORMAL; } - entry.access = file.access; + entry.access = PspAccessBits(file.isDirectory, file.isWritable); entry.exists = file.exists; localtime_r((time_t*)&file.atime, &entry.atime); @@ -960,7 +974,7 @@ std::vector DirectoryFileSystem::GetDirListing(std::string_view pat pspInfo.name = "PSP"; pspInfo.type = FILETYPE_DIRECTORY; pspInfo.size = 4096; - pspInfo.access = 0x777; + pspInfo.access = 0777; pspInfo.exists = true; myVector.push_back(pspInfo); } diff --git a/test.py b/test.py index 949de887a5..8029de327c 100755 --- a/test.py +++ b/test.py @@ -212,6 +212,7 @@ tests_good = [ "intr/vblank/vblank", "io/cwd/cwd", "io/file/rename", + "io/directory/directory", "io/open/badparent", "jpeg/create", "jpeg/delete", @@ -451,7 +452,6 @@ tests_next = [ "intr/registersub", "intr/releasesub", "intr/waits", - "io/directory/directory", "io/file/file", "io/io/io", "io/iodrv/iodrv",