From 745081cc4ecd23a2c4939213e2068de4155e01ef Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 24 Jul 2016 16:03:34 +0200 Subject: [PATCH 1/2] Return errors when trying to close file with pending operations. May help #6357. --- Core/HLE/sceIo.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 9cf1c7b427d9..4cffa1bcbb7d 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -66,7 +66,8 @@ static const int ERROR_ERRNO_FILE_ALREADY_EXISTS = 0x80010011; static const int ERROR_MEMSTICK_DEVCTL_BAD_PARAMS = 0x80220081; static const int ERROR_MEMSTICK_DEVCTL_TOO_MANY_CALLBACKS = 0x80220082; static const int ERROR_KERNEL_BAD_FILE_DESCRIPTOR = 0x80020323; - +static const int ERROR_KERNEL_ILLEGAL_PERMISSION = 0x800200d1; +static const int ERROR_KERNEL_ASYNC_BUSY = 0x80020329; static const int ERROR_PGD_INVALID_HEADER = 0x80510204; /* @@ -277,11 +278,19 @@ static int __IoAllocFd(FileNode *f) { } static void __IoFreeFd(int fd, u32 &error) { - if (fd < PSP_MIN_FD || fd >= PSP_COUNT_FDS) { + if (fd == PSP_STDIN || fd == PSP_STDERR || fd == PSP_STDOUT) { + error = ERROR_KERNEL_ILLEGAL_PERMISSION; + } else if (fd < PSP_MIN_FD || fd >= PSP_COUNT_FDS) { error = ERROR_KERNEL_BAD_FILE_DESCRIPTOR; } else { FileNode *f = __IoGetFd(fd, error); if (f) { + // If there are pending results, don't allow closing. + if (ioManager.HasOperation(f->handle)) { + error = ERROR_KERNEL_ASYNC_BUSY; + return; + } + // Wake anyone waiting on the file before closing it. for (size_t i = 0; i < f->waitingThreads.size(); ++i) { HLEKernel::ResumeFromWait(f->waitingThreads[i], WAITTYPE_ASYNCIO, f->GetUID(), (int)SCE_KERNEL_ERROR_WAIT_DELETE); From 40549b14fd501fffae82bdf59c959052e641ff89 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 24 Jul 2016 21:22:26 +0200 Subject: [PATCH 2/2] Error code cleanup --- Core/HLE/sceIo.cpp | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 4cffa1bcbb7d..b8d9ba3e2eed 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -62,14 +62,9 @@ extern "C" { static const int ERROR_ERRNO_FILE_NOT_FOUND = 0x80010002; static const int ERROR_ERRNO_IO_ERROR = 0x80010005; -static const int ERROR_ERRNO_FILE_ALREADY_EXISTS = 0x80010011; static const int ERROR_MEMSTICK_DEVCTL_BAD_PARAMS = 0x80220081; static const int ERROR_MEMSTICK_DEVCTL_TOO_MANY_CALLBACKS = 0x80220082; -static const int ERROR_KERNEL_BAD_FILE_DESCRIPTOR = 0x80020323; -static const int ERROR_KERNEL_ILLEGAL_PERMISSION = 0x800200d1; -static const int ERROR_KERNEL_ASYNC_BUSY = 0x80020329; static const int ERROR_PGD_INVALID_HEADER = 0x80510204; - /* TODO: async io is missing features! @@ -257,7 +252,7 @@ static void TellFsThreadEnded (SceUID threadID) { static FileNode *__IoGetFd(int fd, u32 &error) { if (fd < 0 || fd >= PSP_COUNT_FDS) { - error = ERROR_KERNEL_BAD_FILE_DESCRIPTOR; + error = SCE_KERNEL_ERROR_BADF; return NULL; } @@ -279,15 +274,15 @@ static int __IoAllocFd(FileNode *f) { static void __IoFreeFd(int fd, u32 &error) { if (fd == PSP_STDIN || fd == PSP_STDERR || fd == PSP_STDOUT) { - error = ERROR_KERNEL_ILLEGAL_PERMISSION; + error = SCE_KERNEL_ERROR_ILLEGAL_PERM; } else if (fd < PSP_MIN_FD || fd >= PSP_COUNT_FDS) { - error = ERROR_KERNEL_BAD_FILE_DESCRIPTOR; + error = SCE_KERNEL_ERROR_BADF; } else { FileNode *f = __IoGetFd(fd, error); if (f) { // If there are pending results, don't allow closing. if (ioManager.HasOperation(f->handle)) { - error = ERROR_KERNEL_ASYNC_BUSY; + error = SCE_KERNEL_ERROR_ASYNC_BUSY; return; } @@ -819,7 +814,7 @@ static bool __IoRead(int &result, int id, u32 data_addr, int size, int &us) { return true; } if (!(f->openMode & FILEACCESS_READ)) { - result = ERROR_KERNEL_BAD_FILE_DESCRIPTOR; + result = SCE_KERNEL_ERROR_BADF; return true; } else if (size < 0) { result = SCE_KERNEL_ERROR_ILLEGAL_ADDR; @@ -958,7 +953,7 @@ static bool __IoWrite(int &result, int id, u32 data_addr, int size, int &us) { return true; } if (!(f->openMode & FILEACCESS_WRITE)) { - result = ERROR_KERNEL_BAD_FILE_DESCRIPTOR; + result = SCE_KERNEL_ERROR_BADF; return true; } if (size < 0) { @@ -1082,7 +1077,7 @@ static u32 sceIoGetDevType(int id) { result = pspFileSystem.DevType(f->handle); } else { ERROR_LOG(SCEIO, "sceIoGetDevType: unknown id %d", id); - result = ERROR_KERNEL_BAD_FILE_DESCRIPTOR; + result = SCE_KERNEL_ERROR_BADF; } return result; @@ -1097,7 +1092,7 @@ static u32 sceIoCancel(int id) // TODO: Cancel the async operation if possible? } else { ERROR_LOG(SCEIO, "sceIoCancel: unknown id %d", id); - error = ERROR_KERNEL_BAD_FILE_DESCRIPTOR; + error = SCE_KERNEL_ERROR_BADF; } return error; @@ -1349,7 +1344,7 @@ static u32 sceIoMkdir(const char *dirname, int mode) { if (pspFileSystem.MkDir(dirname)) return hleDelayResult(0, "mkdir", 1000); else - return hleDelayResult(ERROR_ERRNO_FILE_ALREADY_EXISTS, "mkdir", 1000); + return hleDelayResult(SCE_KERNEL_ERROR_ERRNO_FILE_ALREADY_EXISTS, "mkdir", 1000); } static u32 sceIoRmdir(const char *dirname) {