From edcc17c0dbecd7a24af9d8f596031607b83e0d19 Mon Sep 17 00:00:00 2001 From: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> Date: Mon, 9 Feb 2026 22:43:43 -0600 Subject: [PATCH] fseek implementation Comes with functions fseek calls, aside from fflush which I pushed earlier. --- src/core/libraries/kernel/file_system.h | 1 + .../libc_internal/libc_internal_io.cpp | 65 ++++++++++++++++++- .../libc_internal/libc_internal_io.h | 1 + 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/core/libraries/kernel/file_system.h b/src/core/libraries/kernel/file_system.h index 257a38d0a..1c6e7da97 100644 --- a/src/core/libraries/kernel/file_system.h +++ b/src/core/libraries/kernel/file_system.h @@ -66,6 +66,7 @@ constexpr int ORBIS_KERNEL_O_DIRECT = 0x00010000; constexpr int ORBIS_KERNEL_O_DIRECTORY = 0x00020000; s32 PS4_SYSV_ABI posix_open(const char* path, s32 flags, u16 mode); +s64 PS4_SYSV_ABI posix_lseek(s32 fd, s64 offset, s32 whence); s64 PS4_SYSV_ABI sceKernelWrite(s32 fd, const void* buf, u64 nbytes); s64 PS4_SYSV_ABI sceKernelRead(s32 fd, void* buf, u64 nbytes); s64 PS4_SYSV_ABI sceKernelPread(s32 fd, void* buf, u64 nbytes, s64 offset); diff --git a/src/core/libraries/libc_internal/libc_internal_io.cpp b/src/core/libraries/libc_internal/libc_internal_io.cpp index dd3d4b528..c040c2645 100644 --- a/src/core/libraries/libc_internal/libc_internal_io.cpp +++ b/src/core/libraries/libc_internal/libc_internal_io.cpp @@ -240,10 +240,71 @@ s32 PS4_SYSV_ABI internal_fflush(OrbisFILE* stream) { return 0; } -s32 PS4_SYSV_ABI internal_fseek(OrbisFILE* stream, s64 offset, s32 whence) { +s64 PS4_SYSV_ABI internal__Nnl(OrbisFILE* file, u8* val1, u8* val2) { + if (val1 < val2) { + return val2 - val1; + } return 0; } +s32 PS4_SYSV_ABI internal__Fspos(OrbisFILE* file, Orbisfpos_t* file_pos, s64 offset, s32 whence) { + if ((file->_Mode & 3) == 0) { + return -1; + } + if (internal_fflush(file) != 0) { + return -1; + } + if (whence >= 3) { + *Libraries::Kernel::__Error() = POSIX_EINVAL; + return -1; + } + if (file_pos != nullptr) { + offset = offset + file_pos->_Off; + } + if (whence == 1 && (file->_Mode & 0x1000) != 0) { + s64 val1 = internal__Nnl(file, file->_Rback, &file->_Cbuf); + u8* rsave_ptr = file->_Rsave; + if (rsave_ptr == nullptr) { + rsave_ptr = file->_Rend; + } + s64 val2 = internal__Nnl(file, file->_Next, rsave_ptr); + s64 val3 = internal__Nnl(file, file->_Next, file->_WRend); + offset = offset - (val1 + val2 + val3); + } + s64 result = 0; + if (whence == 2 || (whence == 1 && offset != 0) || (whence == 0 && offset != -1)) { + result = Libraries::Kernel::posix_lseek(file->_Handle, offset, whence); + } + if (result == -1) { + return -1; + } + + u16 file_mode = file->_Mode; + if ((file_mode & 0x3000) != 0) { + u8* file_buf = file->_Buf; + file->_Next = file_buf; + file->_Rend = file_buf; + file->_WRend = file_buf; + file->_Wend = file_buf; + file->_WWend = file_buf; + file->_Rback = &file->_Cbuf; + file->_WRback = &file->unk1; + file->_Rsave = nullptr; + } + if (file_pos != nullptr) { + std::memcpy(&file->_Wstate, &file_pos->_Wstate, sizeof(Orbis_Mbstatet)); + } + file->_Mode = file_mode & 0xceff; + return 0; +} + +s32 PS4_SYSV_ABI internal_fseek(OrbisFILE* stream, s64 offset, s32 whence) { + internal__Lockfilelock(stream); + s32 result = internal__Fspos(stream, nullptr, offset, whence); + internal__Unlockfilelock(stream); + return result; +} + u64 PS4_SYSV_ABI internal_fread(void* ptr, u64 size, u64 nmemb, OrbisFILE* stream) { return 0; } @@ -258,6 +319,8 @@ void RegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("xGT4Mc55ViQ", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Fofind); LIB_FUNCTION("dREVnZkAKRE", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Foprep); LIB_FUNCTION("sQL8D-jio7U", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Fopen); + LIB_FUNCTION("A+Y3xfrWLLo", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Fspos); + LIB_FUNCTION("Ss3108pBuZY", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Nnl); LIB_FUNCTION("vZkmJmvqueY", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Lockfilelock); LIB_FUNCTION("0x7rx8TKy2Y", "libSceLibcInternal", 1, "libSceLibcInternal", diff --git a/src/core/libraries/libc_internal/libc_internal_io.h b/src/core/libraries/libc_internal/libc_internal_io.h index c21ccf3d0..0b8eff599 100644 --- a/src/core/libraries/libc_internal/libc_internal_io.h +++ b/src/core/libraries/libc_internal/libc_internal_io.h @@ -85,6 +85,7 @@ OrbisFILE* PS4_SYSV_ABI internal__Foprep(const char* path, const char* mode, Orb s32 fd, s32 flag1, s32 flag2); s32 PS4_SYSV_ABI internal__Fopen(const char* path, u16 mode, bool flag); OrbisFILE* PS4_SYSV_ABI internal_fopen(const char* path, const char* mode); +s32 PS4_SYSV_ABI internal__Fspos(OrbisFILE* file, Orbisfpos_t* file_pos, s64 offset, s32 whence); s32 PS4_SYSV_ABI internal_fflush(OrbisFILE* stream); s32 PS4_SYSV_ABI internal_fseek(OrbisFILE* stream, s64 offset, s32 whence); u64 PS4_SYSV_ABI internal_fread(void* ptr, u64 size, u64 nmemb, OrbisFILE* stream);