From 12af813b7c963c38444ebc3fed7e8cb0c44620b2 Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Mon, 17 Feb 2025 19:47:45 -0600 Subject: [PATCH] Implement posix_ftruncate Implements posix_ftruncate and fixes errno behavior for sceKernelFtruncate --- src/core/libraries/kernel/file_system.cpp | 56 +++++++++++++++-------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 4cdc21459..7475e590b 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -609,6 +609,42 @@ s32 PS4_SYSV_ABI sceKernelFstat(s32 fd, OrbisKernelStat* sb) { return result; } +s32 PS4_SYSV_ABI posix_ftruncate(s32 fd, s64 length) { + auto* h = Common::Singleton::Instance(); + auto* file = h->GetFile(fd); + + if (file == nullptr) { + *__Error() = POSIX_EBADF; + return -1; + } + + if (file->type == Core::FileSys::FileType::Device) { + s32 result = file->device->ftruncate(length); + if (result < 0) { + ErrSceToPosix(result); + return -1; + } + return result; + } + + if (file->m_host_name.empty()) { + *__Error() = POSIX_EACCES; + return -1; + } + + file->f.SetSize(length); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceKernelFtruncate(s32 fd, s64 length) { + s32 result = posix_ftruncate(fd, length); + if (result < 0) { + LOG_ERROR(Kernel_Fs, "error = {}", *__Error()); + return ErrnoToSceKernelError(*__Error()); + } + return result; +} + s64 PS4_SYSV_ABI sceKernelPreadv(int d, SceKernelIovec* iov, int iovcnt, s64 offset) { if (d < 3) { return ORBIS_KERNEL_ERROR_EPERM; @@ -672,26 +708,6 @@ s32 PS4_SYSV_ABI posix_fsync(int fd) { return result; } -int PS4_SYSV_ABI sceKernelFtruncate(int fd, s64 length) { - auto* h = Common::Singleton::Instance(); - auto* file = h->GetFile(fd); - - if (file == nullptr) { - return ORBIS_KERNEL_ERROR_EBADF; - } - - if (file->type == Core::FileSys::FileType::Device) { - return file->device->ftruncate(length); - } - - if (file->m_host_name.empty()) { - return ORBIS_KERNEL_ERROR_EACCES; - } - - file->f.SetSize(length); - return ORBIS_OK; -} - static int GetDents(int fd, char* buf, int nbytes, s64* basep) { if (fd < 3) { return ORBIS_KERNEL_ERROR_EBADF;