mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-06 20:55:23 +02:00
sceIoRename: refuse wildcards, an existing destination, and don't wait on XDEV
Three ways our rename differed from the PSP's: - A wildcard in either path was passed through to the host, so renaming "test*.txt" could quietly rename a real file. The PSP doesn't expand them here, it rejects them outright. - Renaming onto a file that already exists succeeded, because the host rename() replaces the destination. The PSP refuses, and renaming a file onto itself counts as that too. - Crossing devices returned the right error, but after the same wait as everything else. The hardware fails that one immediately. Fixes io/file/rename, moved to tests_good. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JvJR8oJNSCimCM9KXVLjfq
This commit is contained in:
co-authored by
Claude Opus 5
parent
fd72f308af
commit
5a84f287c4
@@ -2096,12 +2096,32 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
|
||||
return hleNoLog(SCE_KERNEL_ERROR_UNSUP);
|
||||
}
|
||||
|
||||
static bool IoPathHasWildcard(const char *path) {
|
||||
return path && strpbrk(path, "*?") != nullptr;
|
||||
}
|
||||
|
||||
static u32 sceIoRename(const char *from, const char *to) {
|
||||
// TODO: Timing isn't terribly accurate.
|
||||
|
||||
// sceIoRename doesn't expand wildcards, it refuses them - in either path, and before it
|
||||
// looks at whether anything is actually there.
|
||||
if (IoPathHasWildcard(from) || IoPathHasWildcard(to)) {
|
||||
return hleDelayResult(hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT, "wildcard in path"), "file renamed", 1000);
|
||||
}
|
||||
|
||||
if (!pspFileSystem.GetFileInfo(from).exists)
|
||||
return hleDelayResult(hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND), "file renamed", 1000);
|
||||
|
||||
// The PSP won't rename onto something that already exists, and renaming a file onto itself
|
||||
// counts. Host rename() would happily replace the destination.
|
||||
if (pspFileSystem.GetFileInfo(to).exists)
|
||||
return hleDelayResult(hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_FILE_ALREADY_EXISTS, "destination exists"), "file renamed", 1000);
|
||||
|
||||
int result = pspFileSystem.RenameFile(from, to);
|
||||
if (result == (int)SCE_KERNEL_ERROR_XDEV) {
|
||||
// Renaming across devices is refused up front, without the wait the other errors take.
|
||||
return hleLogError(Log::sceIo, result, "cannot rename across devices");
|
||||
}
|
||||
if (result < 0)
|
||||
WARN_LOG(Log::sceIo, "Could not move %s to %s", from, to);
|
||||
return hleDelayResult(hleLogDebug(Log::sceIo, result), "file renamed", 1000);
|
||||
|
||||
@@ -211,6 +211,7 @@ tests_good = [
|
||||
"intr/suspended",
|
||||
"intr/vblank/vblank",
|
||||
"io/cwd/cwd",
|
||||
"io/file/rename",
|
||||
"io/open/badparent",
|
||||
"jpeg/create",
|
||||
"jpeg/delete",
|
||||
@@ -452,7 +453,6 @@ tests_next = [
|
||||
"intr/waits",
|
||||
"io/directory/directory",
|
||||
"io/file/file",
|
||||
"io/file/rename",
|
||||
"io/io/io",
|
||||
"io/iodrv/iodrv",
|
||||
"io/open/tty0",
|
||||
|
||||
Reference in New Issue
Block a user