if (syscall_no == SYSCALL_PREAD || syscall_no == SYSCALL_PWRITE ||
syscall_no == SYSCALL_ACCESS || syscall_no == SYSCALL_TRUNCATE ||
- syscall_no == SYSCALL_FTRUNCATE) {
+ syscall_no == SYSCALL_FTRUNCATE || syscall_no == SYSCALL_READV ||
+ syscall_no == SYSCALL_WRITEV) {
posix_ext_syscall_dispatch(regs, syscall_no);
return;
}
return;
}
+ if (syscall_no == SYSCALL_READV) {
+ int fd = (int)regs->ebx;
+ struct { void* iov_base; uint32_t iov_len; } iov;
+ const void* user_iov = (const void*)regs->ecx;
+ int iovcnt = (int)regs->edx;
+ if (iovcnt <= 0 || iovcnt > 16) { regs->eax = (uint32_t)-EINVAL; return; }
+ uint32_t total = 0;
+ for (int i = 0; i < iovcnt; i++) {
+ if (copy_from_user(&iov, (const char*)user_iov + i * 8, 8) < 0) {
+ regs->eax = (uint32_t)-EFAULT; return;
+ }
+ if (iov.iov_len == 0) continue;
+ int r = syscall_read_impl(fd, iov.iov_base, iov.iov_len);
+ if (r < 0) { if (total == 0) { regs->eax = (uint32_t)r; return; } break; }
+ total += (uint32_t)r;
+ if ((uint32_t)r < iov.iov_len) break;
+ }
+ regs->eax = total;
+ return;
+ }
+
+ if (syscall_no == SYSCALL_WRITEV) {
+ int fd = (int)regs->ebx;
+ struct { const void* iov_base; uint32_t iov_len; } iov;
+ const void* user_iov = (const void*)regs->ecx;
+ int iovcnt = (int)regs->edx;
+ if (iovcnt <= 0 || iovcnt > 16) { regs->eax = (uint32_t)-EINVAL; return; }
+ uint32_t total = 0;
+ for (int i = 0; i < iovcnt; i++) {
+ if (copy_from_user(&iov, (const char*)user_iov + i * 8, 8) < 0) {
+ regs->eax = (uint32_t)-EFAULT; return;
+ }
+ if (iov.iov_len == 0) continue;
+ int r = syscall_write_impl(fd, iov.iov_base, iov.iov_len);
+ if (r < 0) { if (total == 0) { regs->eax = (uint32_t)r; return; } break; }
+ total += (uint32_t)r;
+ if ((uint32_t)r < iov.iov_len) break;
+ }
+ regs->eax = total;
+ return;
+ }
+
regs->eax = (uint32_t)-ENOSYS;
}
--- /dev/null
+#include "sys/uio.h"
+#include "syscall.h"
+#include "errno.h"
+
+int readv(int fd, const struct iovec* iov, int iovcnt) {
+ return __syscall_ret(_syscall3(SYS_READV, fd, (int)iov, iovcnt));
+}
+
+int writev(int fd, const struct iovec* iov, int iovcnt) {
+ return __syscall_ret(_syscall3(SYS_WRITEV, fd, (int)iov, iovcnt));
+}