summaryrefslogtreecommitdiff
path: root/sys/compat/linux/common
diff options
context:
space:
mode:
authorthorpej <thorpej@NetBSD.org>2021-09-20 02:20:02 +0000
committerthorpej <thorpej@NetBSD.org>2021-09-20 02:20:02 +0000
commitce1f7c4e8f4ee0cdcfa7972f15dfb6832fa259fd (patch)
tree5e896d9a365575353c6597d46dabde81dbdb6fb6 /sys/compat/linux/common
parentfc6d8cac7f90286072cdb8be99ff04e905aa2efe (diff)
Add preadv(2) and pwritev(2) system calls to COMPAT_LINUX and COMPAT_LINUX32.
Diffstat (limited to 'sys/compat/linux/common')
-rw-r--r--sys/compat/linux/common/linux_file.c71
1 files changed, 69 insertions, 2 deletions
diff --git a/sys/compat/linux/common/linux_file.c b/sys/compat/linux/common/linux_file.c
index 36ae0e429b1..429ab4b2aab 100644
--- a/sys/compat/linux/common/linux_file.c
+++ b/sys/compat/linux/common/linux_file.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_file.c,v 1.119 2021/09/07 11:43:04 riastradh Exp $ */
+/* $NetBSD: linux_file.c,v 1.120 2021/09/20 02:20:03 thorpej Exp $ */
/*-
* Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_file.c,v 1.119 2021/09/07 11:43:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_file.c,v 1.120 2021/09/20 02:20:03 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -136,6 +136,23 @@ bsd_to_linux_ioflags(int bflags)
return res;
}
+static inline off_t
+linux_hilo_to_off_t(unsigned long hi, unsigned long lo)
+{
+#ifdef _LP64
+ /*
+ * Linux discards the "hi" portion on LP64 platforms; even though
+ * glibc puts of the upper 32-bits of the offset into the "hi"
+ * argument regardless, the "lo" argument has all the bits in
+ * this case.
+ */
+ (void) hi;
+ return (off_t)lo;
+#else
+ return (((off_t)hi) << 32) | lo;
+#endif /* _LP64 */
+}
+
/*
* creat(2) is an obsolete function, but it's present as a Linux
* system call, so let's deal with it.
@@ -785,6 +802,56 @@ linux_sys_pwrite(struct lwp *l, const struct linux_sys_pwrite_args *uap, registe
return sys_pwrite(l, &pra, retval);
}
+/*
+ * preadv(2)
+ */
+int
+linux_sys_preadv(struct lwp *l, const struct linux_sys_preadv_args *uap,
+ register_t *retval)
+{
+ /* {
+ syscallarg(int) fd;
+ syscallarg(const struct iovec *) iovp;
+ syscallarg(int) iovcnt;
+ syscallarg(unsigned long) off_lo;
+ syscallarg(unsigned long) off_hi;
+ } */
+ struct sys_preadv_args ua;
+
+ SCARG(&ua, fd) = SCARG(uap, fd);
+ SCARG(&ua, iovp) = SCARG(uap, iovp);
+ SCARG(&ua, iovcnt) = SCARG(uap, iovcnt);
+ SCARG(&ua, PAD) = 0;
+ SCARG(&ua, offset) = linux_hilo_to_off_t(SCARG(uap, off_hi),
+ SCARG(uap, off_lo));
+ return sys_preadv(l, &ua, retval);
+}
+
+/*
+ * pwritev(2)
+ */
+int
+linux_sys_pwritev(struct lwp *l, const struct linux_sys_pwritev_args *uap,
+ register_t *retval)
+{
+ /* {
+ syscallarg(int) fd;
+ syscallarg(const struct iovec *) iovp;
+ syscallarg(int) iovcnt;
+ syscallarg(unsigned long) off_lo;
+ syscallarg(unsigned long) off_hi;
+ } */
+ struct sys_pwritev_args ua;
+
+ SCARG(&ua, fd) = SCARG(uap, fd);
+ SCARG(&ua, iovp) = (const void *)SCARG(uap, iovp);
+ SCARG(&ua, iovcnt) = SCARG(uap, iovcnt);
+ SCARG(&ua, PAD) = 0;
+ SCARG(&ua, offset) = linux_hilo_to_off_t(SCARG(uap, off_hi),
+ SCARG(uap, off_lo));
+ return sys_pwritev(l, &ua, retval);
+}
+
int
linux_sys_dup3(struct lwp *l, const struct linux_sys_dup3_args *uap,
register_t *retval)