Skip to content

Commit

Permalink
fix(monika): Fix Haiku read[v]/write[v] syscalls
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
trungnt2910 committed Mar 5, 2024
1 parent b759b73 commit cf41cf8
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions monika/linux/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit cf41cf8

Please sign in to comment.