diff options
| author | Dominique Martinet <dominique.martinet@atmark-techno.com> | 2026-06-10 07:54:52 +0000 |
|---|---|---|
| committer | Michael Tokarev <mjt@tls.msk.ru> | 2026-06-14 08:53:07 +0300 |
| commit | ad16d5938d3f08c58ac8a7888a827f33ddf37d26 (patch) | |
| tree | 6a293966c35a155e3d5f545959316bb6de9a034d | |
| parent | 0528c5b23f58312b7e163e4a4d9e4c79b7df2e7e (diff) | |
| download | qemu-ad16d5938d3f08c58ac8a7888a827f33ddf37d26.tar.gz qemu-ad16d5938d3f08c58ac8a7888a827f33ddf37d26.zip | |
linux-user: add preadv2/preadv2
Some programs apparently use these, like the python test suite.
The flags argument (rwf_t) is an int, with values shared on all arches
and does not need translating.
This was tested manually with the following python script:
```
import os
fd = os.open('test', os.O_RDWR|os.O_CREAT)
os.pwritev(fd, [b'test', b'ok'], 0, os.RWF_HIPRI)
buf = [bytearray(3), bytearray(10)]
os.preadv(fd, buf, 0, os.RWF_HIPRI)
print(buf[0])
print(buf[1])
```
Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit fb4c08147ba79c552897427a42e3b24b38712786)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
| -rw-r--r-- | linux-user/syscall.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 993718973a..11d3b41dff 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -741,6 +741,11 @@ safe_syscall5(ssize_t, preadv, int, fd, const struct iovec *, iov, int, iovcnt, unsigned long, pos_l, unsigned long, pos_h) safe_syscall5(ssize_t, pwritev, int, fd, const struct iovec *, iov, int, iovcnt, unsigned long, pos_l, unsigned long, pos_h) +safe_syscall6(ssize_t, preadv2, int, fd, const struct iovec *, iov, int, iovcnt, + unsigned long, pos_l, unsigned long, pos_h, __kernel_rwf_t, flags) +safe_syscall6(ssize_t, pwritev2, int, fd, const struct iovec *, iov, + int, iovcnt, unsigned long, pos_l, unsigned long, pos_h, + __kernel_rwf_t, flags) safe_syscall3(int, connect, int, fd, const struct sockaddr *, addr, socklen_t, addrlen) safe_syscall6(ssize_t, sendto, int, fd, const void *, buf, size_t, len, @@ -11848,6 +11853,39 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, } return ret; #endif +#if defined(TARGET_NR_preadv2) + case TARGET_NR_preadv2: + { + struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0); + if (vec != NULL) { + unsigned long low, high; + + target_to_host_low_high(arg4, arg5, &low, &high); + ret = get_errno(safe_preadv2(arg1, vec, arg3, low, high, arg6)); + unlock_iovec(vec, arg2, arg3, 1); + } else { + ret = -host_to_target_errno(errno); + } + } + return ret; +#endif +#if defined(TARGET_NR_pwritev2) + case TARGET_NR_pwritev2: + { + struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1); + if (vec != NULL) { + unsigned long low, high; + + target_to_host_low_high(arg4, arg5, &low, &high); + ret = get_errno(safe_pwritev2(arg1, vec, arg3, low, high, + arg6)); + unlock_iovec(vec, arg2, arg3, 0); + } else { + ret = -host_to_target_errno(errno); + } + } + return ret; +#endif case TARGET_NR_getsid: return get_errno(getsid(arg1)); #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */ |
