From b2c3da432ca5eaf18a88312a395d03d6e24d2a0f Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Mon, 24 Mar 2025 12:52:30 -0500 Subject: [PATCH] Remove inaccurate error behavior Seek can have offsets past the end of a file. Also add logging for two valid whence values that are unsupported on Windows. I'll need to verify that SEEK_HOLE and SEEK_DATA correspond to 3 and 4 respectively, I've yet to check source to verify. --- src/common/io_file.cpp | 4 +++- src/common/io_file.h | 2 ++ src/core/libraries/kernel/file_system.cpp | 9 ++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/common/io_file.cpp b/src/common/io_file.cpp index 067010a26..8c75120cc 100644 --- a/src/common/io_file.cpp +++ b/src/common/io_file.cpp @@ -125,12 +125,14 @@ namespace { [[nodiscard]] constexpr int ToSeekOrigin(SeekOrigin origin) { switch (origin) { case SeekOrigin::SetOrigin: - default: return SEEK_SET; case SeekOrigin::CurrentPosition: return SEEK_CUR; case SeekOrigin::End: return SEEK_END; + default: + LOG_ERROR(Core, "Unsupported origin {}, defaulting to SEEK_SET", origin); + return SEEK_SET; } } diff --git a/src/common/io_file.h b/src/common/io_file.h index 45787a092..fb20a2bc5 100644 --- a/src/common/io_file.h +++ b/src/common/io_file.h @@ -61,6 +61,8 @@ enum class SeekOrigin : u32 { SetOrigin, // Seeks from the start of the file. CurrentPosition, // Seeks from the current file pointer position. End, // Seeks from the end of the file. + SeekHole, // Seeks from the start of the next hole in the file. + SeekData, // Seeks from the start of the next non-hole region in the file. }; class IOFile final { diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index fb4b02fdb..dc13b6721 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -367,6 +367,10 @@ s64 PS4_SYSV_ABI posix_lseek(s32 fd, s64 offset, s32 whence) { origin = Common::FS::SeekOrigin::CurrentPosition; } else if (whence == 2) { origin = Common::FS::SeekOrigin::End; + } else if (whence == 3) { + origin = Common::FS::SeekOrigin::SeekHole; + } else if (whence == 4) { + origin = Common::FS::SeekOrigin::SeekData; } else { // whence parameter is invalid *__Error() = POSIX_EINVAL; @@ -377,10 +381,9 @@ s64 PS4_SYSV_ABI posix_lseek(s32 fd, s64 offset, s32 whence) { if (errno != 0) { // Seek failed in platform-specific code, errno needs to be converted. SetPosixErrno(errno); - } else { - // Seek failed because offset is beyond the end of the file. - *__Error() = POSIX_ENXIO; + return -1; } + // Shouldn't be possible, but just in case. return -1; }