From dd027c6d36ac44c55d1e8dfda60f18cdcc663fb7 Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Mon, 17 Feb 2025 18:35:54 -0600 Subject: [PATCH] Implement posix_writev and sceKernelWritev Also fixes error behavior on writev, since it shouldn't ever return kernel errors (since our device files return those) --- src/core/libraries/kernel/file_system.cpp | 27 +++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 5ec1c379b..ac1c9cea7 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -291,25 +291,44 @@ size_t PS4_SYSV_ABI sceKernelReadv(s32 fd, const SceKernelIovec* iov, s32 iovcnt return result; } -size_t PS4_SYSV_ABI writev(int fd, const SceKernelIovec* iov, int iovcn) { +size_t PS4_SYSV_ABI writev(s32 fd, const SceKernelIovec* iov, s32 iovcnt) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(fd); if (file == nullptr) { - return ORBIS_KERNEL_ERROR_EBADF; + *__Error() = POSIX_EBADF; + return -1; } std::scoped_lock lk{file->m_mutex}; if (file->type == Core::FileSys::FileType::Device) { - return file->device->writev(iov, iovcn); + size_t result = file->device->writev(iov, iovcnt); + if (result < 0) { + ErrSceToPosix(result); + return -1; + } + return result; } size_t total_written = 0; - for (int i = 0; i < iovcn; i++) { + for (s32 i = 0; i < iovcnt; i++) { total_written += file->f.WriteRaw(iov[i].iov_base, iov[i].iov_len); } return total_written; } +size_t PS4_SYSV_ABI posix_writev(int fd, const SceKernelIovec* iov, int iovcnt) { + return writev(fd, iov, iovcnt); +} + +size_t PS4_SYSV_ABI sceKernelWritev(int fd, const SceKernelIovec* iov, int iovcnt) { + size_t result = writev(fd, iov, iovcnt); + if (result < 0) { + LOG_ERROR(Kernel_Fs, "writev: error = {}", *__Error()); + return ErrnoToSceKernelError(*__Error()); + } + return result; +} + s64 PS4_SYSV_ABI sceKernelLseek(int d, s64 offset, int whence) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(d);