diff options
author | Patrick Mooney <pmooney@pfmooney.com> | 2016-08-11 21:29:02 +0000 |
---|---|---|
committer | Patrick Mooney <pmooney@pfmooney.com> | 2016-08-19 19:14:28 +0000 |
commit | 533b6005f11009bfbddd0c485c45a745d6ca290f (patch) | |
tree | 0c887dfec96391a617b55e61083f8d3d4017b204 | |
parent | 926f7c1c9f70982389660a5240eabff26fec931b (diff) | |
download | illumos-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.c | 57 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/lx_brand.c | 6 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_syscall.c | 6 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_syscalls.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_lseek.c | 81 | ||||
-rw-r--r-- | usr/src/uts/intel/Makefile.files | 1 |
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 \ |