summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2016-08-11 21:29:02 +0000
committerPatrick Mooney <pmooney@pfmooney.com>2016-08-19 19:14:28 +0000
commit533b6005f11009bfbddd0c485c45a745d6ca290f (patch)
tree0c887dfec96391a617b55e61083f8d3d4017b204
parent926f7c1c9f70982389660a5240eabff26fec931b (diff)
downloadillumos-joyent-533b6005f11009bfbddd0c485c45a745d6ca290f.tar.gz
OS-5583 lxbrand convert lseek to IKE
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/file.c57
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/lx_brand.c6
-rw-r--r--usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h2
-rw-r--r--usr/src/uts/common/brand/lx/os/lx_syscall.c6
-rw-r--r--usr/src/uts/common/brand/lx/sys/lx_syscalls.h3
-rw-r--r--usr/src/uts/common/brand/lx/syscall/lx_lseek.c81
-rw-r--r--usr/src/uts/intel/Makefile.files1
7 files changed, 91 insertions, 65 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/file.c b/usr/src/lib/brand/lx/lx_brand/common/file.c
index 6fc7a5e5dd..d0d2dc8bae 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/file.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/file.c
@@ -236,63 +236,6 @@ lx_utime(uintptr_t p1, uintptr_t p2)
return (0);
}
-#if defined(_ILP32)
-/*
- * llseek() - The Linux implementation takes an additional parameter, which is
- * the resulting position in the file.
- */
-long
-lx_llseek(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4,
- uintptr_t p5)
-{
- offset_t ret;
- offset_t *res = (offset_t *)p4;
-
- /* SEEK_DATA and SEEK_HOLE are only valid in Solaris */
- if ((int)p5 > SEEK_END)
- return (-EINVAL);
-
- if ((ret = llseek((int)p1, LX_32TO64(p3, p2), p5)) < 0)
- return (-errno);
-
- *res = ret;
- return (0);
-}
-#endif
-
-/*
- * seek() - For 32-bit lx, when the resultant file offset cannot be represented
- * in 32 bits, Linux performs the seek but Illumos doesn't, though both set
- * EOVERFLOW. We call llseek() and then check to see if we need to return
- * EOVERFLOW.
- */
-long
-lx_lseek(uintptr_t p1, uintptr_t p2, uintptr_t p3)
-{
- offset_t offset = (offset_t)(off_t)(p2); /* sign extend */
- offset_t ret;
-#if defined(_ILP32)
- off_t ret32;
-#endif
-
- /* SEEK_DATA and SEEK_HOLE are only valid in Illumos */
- if ((int)p3 > SEEK_END)
- return (-EINVAL);
-
- if ((ret = llseek((int)p1, offset, p3)) < 0)
- return (-errno);
-
-#if defined(_LP64)
- return (ret);
-#else
- ret32 = (off_t)ret;
- if ((offset_t)ret32 == ret)
- return (ret32);
- else
- return (-EOVERFLOW);
-#endif
-}
-
/*
* Neither Illumos nor Linux actually returns anything to the caller, but glibc
* expects to see SOME value returned, so placate it and return 0.
diff --git a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
index 5f71e6286e..e85c19e6dd 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
@@ -1019,7 +1019,7 @@ static lx_syscall_handler_t lx_handlers[] = {
NULL, /* 5: fstat */
NULL, /* 6: lstat */
NULL, /* 7: poll */
- lx_lseek, /* 8: lseek */
+ NULL, /* 8: lseek */
lx_mmap, /* 9: mmap */
lx_mprotect, /* 10: mprotect */
lx_munmap, /* 11: munmap */
@@ -1361,7 +1361,7 @@ static lx_syscall_handler_t lx_handlers[] = {
NULL, /* 16: lchown16 */
NULL, /* 17: break */
NULL, /* 18: stat */
- lx_lseek, /* 19: lseek */
+ NULL, /* 19: lseek */
NULL, /* 20: getpid */
lx_mount, /* 21: mount */
lx_umount, /* 22: umount */
@@ -1482,7 +1482,7 @@ static lx_syscall_handler_t lx_handlers[] = {
NULL, /* 137: afs_syscall */
lx_setfsuid16, /* 138: setfsuid16 */
lx_setfsgid16, /* 139: setfsgid16 */
- lx_llseek, /* 140: llseek */
+ NULL, /* 140: llseek */
NULL, /* 141: getdents */
NULL, /* 142: select */
lx_flock, /* 143: flock */
diff --git a/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h b/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h
index 5b46311a3e..8369298514 100644
--- a/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h
+++ b/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h
@@ -127,8 +127,6 @@ extern long lx_unlink(uintptr_t);
extern long lx_rmdir(uintptr_t);
extern long lx_rename(uintptr_t, uintptr_t);
extern long lx_utime(uintptr_t, uintptr_t);
-extern long lx_llseek(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
-extern long lx_lseek(uintptr_t, uintptr_t, uintptr_t);
extern long lx_sysfs(uintptr_t, uintptr_t, uintptr_t);
extern long lx_uname(uintptr_t);
diff --git a/usr/src/uts/common/brand/lx/os/lx_syscall.c b/usr/src/uts/common/brand/lx/os/lx_syscall.c
index 35020f4fe6..f360225974 100644
--- a/usr/src/uts/common/brand/lx/os/lx_syscall.c
+++ b/usr/src/uts/common/brand/lx/os/lx_syscall.c
@@ -540,7 +540,7 @@ lx_sysent_t lx_sysent32[] = {
{"lchown16", lx_lchown16, 0, 3}, /* 16 */
{"break", NULL, NOSYS_OBSOLETE, 0}, /* 17 */
{"stat", NULL, NOSYS_OBSOLETE, 0}, /* 18 */
- {"lseek", NULL, 0, 3}, /* 19 */
+ {"lseek", lx_lseek32, 0, 3}, /* 19 */
{"getpid", lx_getpid, 0, 0}, /* 20 */
{"mount", NULL, 0, 5}, /* 21 */
{"umount", NULL, 0, 1}, /* 22 */
@@ -661,7 +661,7 @@ lx_sysent_t lx_sysent32[] = {
{"afs_syscall", NULL, NOSYS_KERNEL, 0}, /* 137 */
{"setfsuid16", NULL, 0, 1}, /* 138 */
{"setfsgid16", NULL, 0, 1}, /* 139 */
- {"llseek", NULL, 0, 5}, /* 140 */
+ {"llseek", lx_llseek, 0, 5}, /* 140 */
{"getdents", lx_getdents_32, 0, 3}, /* 141 */
{"select", lx_select, 0, 5}, /* 142 */
{"flock", NULL, 0, 2}, /* 143 */
@@ -900,7 +900,7 @@ lx_sysent_t lx_sysent64[] = {
{"fstat", lx_fstat64, 0, 2}, /* 5 */
{"lstat", lx_lstat64, 0, 2}, /* 6 */
{"poll", lx_poll, 0, 3}, /* 7 */
- {"lseek", NULL, 0, 3}, /* 8 */
+ {"lseek", lx_lseek64, 0, 3}, /* 8 */
{"mmap", NULL, 0, 6}, /* 9 */
{"mprotect", NULL, 0, 3}, /* 10 */
{"munmap", NULL, 0, 2}, /* 11 */
diff --git a/usr/src/uts/common/brand/lx/sys/lx_syscalls.h b/usr/src/uts/common/brand/lx/sys/lx_syscalls.h
index ff9674b2c5..5b46e66035 100644
--- a/usr/src/uts/common/brand/lx/sys/lx_syscalls.h
+++ b/usr/src/uts/common/brand/lx/sys/lx_syscalls.h
@@ -100,7 +100,10 @@ extern long lx_link();
extern long lx_linkat();
extern long lx_listen();
extern long lx_llistxattr();
+extern long lx_llseek();
extern long lx_lremovexattr();
+extern long lx_lseek32();
+extern long lx_lseek64();
extern long lx_lsetxattr();
extern long lx_lstat32();
extern long lx_lstat64();
diff --git a/usr/src/uts/common/brand/lx/syscall/lx_lseek.c b/usr/src/uts/common/brand/lx/syscall/lx_lseek.c
new file mode 100644
index 0000000000..75a178dcc6
--- /dev/null
+++ b/usr/src/uts/common/brand/lx/syscall/lx_lseek.c
@@ -0,0 +1,81 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/thread.h>
+#include <sys/errno.h>
+#include <sys/debug.h>
+
+
+#if defined(_SYSCALL32_IMPL) || defined(_ILP32)
+
+/* from uts/common/syscalls/lseek.c */
+extern offset_t llseek32(int32_t, uint32_t, uint32_t, int);
+extern off32_t lseek32(int32_t, off32_t, int32_t);
+
+long
+lx_llseek(int fd, uint32_t off_high, uint32_t off_low, void *out, int whence)
+{
+ offset_t res;
+
+ ASSERT(get_udatamodel() == DATAMODEL_ILP32);
+ res = llseek32(fd, off_low, off_high, whence);
+ if (ttolwp(curthread)->lwp_errno == 0) {
+ if (copyout(&res, out, sizeof (offset_t)) != 0) {
+ return (set_errno(EFAULT));
+ }
+ }
+ return (ttolwp(curthread)->lwp_errno);
+}
+
+
+long
+lx_lseek32(int fd, off32_t offset, int whence)
+{
+ offset_t res;
+
+ /*
+ * When returning EOVERFLOW for an offset which is outside the bounds
+ * of an off32_t, Linux will still perform the actual seek before
+ * yielding EOVERFLOW.
+ *
+ * In order to emulate that behavior, an llseek bound to the 64-bit
+ * boundary is used. The overflow can then be reported after the
+ * successful seek.
+ */
+ ASSERT(get_udatamodel() == DATAMODEL_ILP32);
+ res = llseek32(fd, 0, (uint32_t)offset, whence);
+ if (ttolwp(curthread)->lwp_errno == 0 && res > MAXOFF32_T) {
+ return (set_errno(EOVERFLOW));
+ }
+ return (res);
+
+}
+#endif /* defined(_SYSCALL32_IMPL) || defined(_ILP32) */
+
+#if defined(_LP64)
+
+/* from uts/common/syscalls/lseek.c */
+extern off_t lseek64(int, off_t, int);
+
+long
+lx_lseek64(int fd, off_t offset, int whence)
+{
+ ASSERT(get_udatamodel() == DATAMODEL_LP64);
+ return (lseek64(fd, offset, whence));
+}
+
+#endif /* defined(_LP64) */
diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files
index d31a5f3815..d279def122 100644
--- a/usr/src/uts/intel/Makefile.files
+++ b/usr/src/uts/intel/Makefile.files
@@ -331,6 +331,7 @@ LX_BRAND_OBJS = \
lx_ioprio.o \
lx_kill.o \
lx_link.o \
+ lx_lseek.o \
lx_misc.o \
lx_mkdir.o \
lx_modify_ldt.o \