Skip to content

Commit cf41cf8

Browse files
committed
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.
1 parent b759b73 commit cf41cf8

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

monika/linux/io.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ ssize_t _moni_write(int fd, haiku_off_t pos, const void* buffer, size_t bufferSi
137137
else
138138
{
139139
bytesWritten = LINUX_SYSCALL4(__NR_pwrite64, fd, buffer, bufferSize, pos);
140+
if (bytesWritten == -ESPIPE)
141+
{
142+
// On Haiku, write_pos ignores the `pos` parameter for non-seekable devices
143+
// instead of returning an error.
144+
bytesWritten = LINUX_SYSCALL3(__NR_write, fd, buffer, bufferSize);
145+
}
140146
}
141147

142148
if (bytesWritten < 0)
@@ -175,6 +181,10 @@ ssize_t _moni_writev(int fd, haiku_off_t pos, const struct haiku_iovec *vecs, si
175181
{
176182
// Last two params: Low and high order bytes of pos.
177183
bytesWritten = LINUX_SYSCALL5(__NR_pwritev, fd, linuxVecs, count, (uint32_t)pos, ((uint64_t)pos) >> 32);
184+
if (bytesWritten == -ESPIPE)
185+
{
186+
bytesWritten = LINUX_SYSCALL3(__NR_writev, fd, linuxVecs, count);
187+
}
178188
}
179189

180190
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)
198208
else
199209
{
200210
bytesRead = LINUX_SYSCALL4(__NR_pread64, fd, buffer, bufferSize, pos);
211+
if (bytesRead == -ESPIPE)
212+
{
213+
bytesRead = LINUX_SYSCALL3(__NR_read, fd, buffer, bufferSize);
214+
}
201215
}
202216

203217
if (bytesRead < 0)
@@ -236,6 +250,10 @@ ssize_t _moni_readv(int fd, off_t pos, const struct haiku_iovec *vecs, size_t co
236250
{
237251
// Last two params: Low and high order bytes of pos.
238252
bytesRead = LINUX_SYSCALL5(__NR_preadv, fd, linuxVecs, count, (uint32_t)pos, ((uint64_t)pos) >> 32);
253+
if (bytesRead == -ESPIPE)
254+
{
255+
bytesRead = LINUX_SYSCALL3(__NR_readv, fd, linuxVecs, count);
256+
}
239257
}
240258

241259
LINUX_SYSCALL2(__NR_munmap, linuxVecs, memSize);

0 commit comments

Comments
 (0)