From cf41cf872e746fca2a2d1e009fbd3ed91f266cda Mon Sep 17 00:00:00 2001 From: Trung Nguyen <57174311+trungnt2910@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:30:56 +0000 Subject: [PATCH] fix(monika): Fix Haiku read[v]/write[v] syscalls On non-seekable devices, the position argument is simply ignored and does not trigger an error. We emulate this behavior by detecting `EISPIPE` then forwarding the call to the appropraite non-seeking functions. --- monika/linux/io.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/monika/linux/io.cpp b/monika/linux/io.cpp index e2a4363..11abc26 100644 --- a/monika/linux/io.cpp +++ b/monika/linux/io.cpp @@ -137,6 +137,12 @@ ssize_t _moni_write(int fd, haiku_off_t pos, const void* buffer, size_t bufferSi else { bytesWritten = LINUX_SYSCALL4(__NR_pwrite64, fd, buffer, bufferSize, pos); + if (bytesWritten == -ESPIPE) + { + // On Haiku, write_pos ignores the `pos` parameter for non-seekable devices + // instead of returning an error. + bytesWritten = LINUX_SYSCALL3(__NR_write, fd, buffer, bufferSize); + } } if (bytesWritten < 0) @@ -175,6 +181,10 @@ ssize_t _moni_writev(int fd, haiku_off_t pos, const struct haiku_iovec *vecs, si { // Last two params: Low and high order bytes of pos. bytesWritten = LINUX_SYSCALL5(__NR_pwritev, fd, linuxVecs, count, (uint32_t)pos, ((uint64_t)pos) >> 32); + if (bytesWritten == -ESPIPE) + { + bytesWritten = LINUX_SYSCALL3(__NR_writev, fd, linuxVecs, count); + } } LINUX_SYSCALL2(__NR_munmap, linuxVecs, memSize); @@ -198,6 +208,10 @@ ssize_t _moni_read(int fd, haiku_off_t pos, void* buffer, size_t bufferSize) else { bytesRead = LINUX_SYSCALL4(__NR_pread64, fd, buffer, bufferSize, pos); + if (bytesRead == -ESPIPE) + { + bytesRead = LINUX_SYSCALL3(__NR_read, fd, buffer, bufferSize); + } } if (bytesRead < 0) @@ -236,6 +250,10 @@ ssize_t _moni_readv(int fd, off_t pos, const struct haiku_iovec *vecs, size_t co { // Last two params: Low and high order bytes of pos. bytesRead = LINUX_SYSCALL5(__NR_preadv, fd, linuxVecs, count, (uint32_t)pos, ((uint64_t)pos) >> 32); + if (bytesRead == -ESPIPE) + { + bytesRead = LINUX_SYSCALL3(__NR_readv, fd, linuxVecs, count); + } } LINUX_SYSCALL2(__NR_munmap, linuxVecs, memSize);