summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorvk210190 <none@none>2008-03-17 02:50:29 -0700
committervk210190 <none@none>2008-03-17 02:50:29 -0700
commit861d78e4c6cbc13ae7d45c5d1d2cb5acf0b408f7 (patch)
treeb755a077f6b726db3da613d82a542c7b6073fc22 /usr/src
parent94cf82d0ee8fe71ca5efd060d6241bf36e66fee7 (diff)
downloadillumos-joyent-861d78e4c6cbc13ae7d45c5d1d2cb5acf0b408f7.tar.gz
6661506 LTP bug : pwrite04 fails because O_APPEND flag is not handled in similar way in Solaris and Linux
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/iovec.c37
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/lx_brand.c4
-rw-r--r--usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h3
3 files changed, 40 insertions, 4 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/iovec.c b/usr/src/lib/brand/lx/lx_brand/common/iovec.c
index c9b48fb173..49af88d22e 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/iovec.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/iovec.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -88,6 +88,41 @@ lx_pread64(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5)
}
/*
+ * On Linux, the pwrite(2) system call behaves identically to Solaris except
+ * in the case of the file being opened with O_APPEND. In that case Linux's
+ * pwrite(2) ignores the offset parameter and instead appends the data to the
+ * file without modifying the current seek pointer.
+ */
+int
+lx_pwrite64(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4,
+ uintptr_t p5)
+{
+ int fd = (int)p1;
+ void *buf = (void *)p2;
+ size_t nbyte = (size_t)p3;
+ uintptr_t off_lo = p4;
+ uintptr_t off_hi = p5;
+ ssize_t ret;
+ int rval;
+ struct stat64 statbuf;
+
+ if ((rval = fcntl(fd, F_GETFL, 0)) < 0)
+ return (-errno);
+
+ if (!(rval & O_APPEND)) {
+ ret = pwrite64(fd, buf, nbyte,
+ (off64_t)LX_32TO64(off_lo, off_hi));
+ } else if ((ret = fstat64(fd, &statbuf)) == 0) {
+ ret = pwrite64(fd, buf, nbyte, statbuf.st_size);
+ }
+
+ if (ret < 0)
+ return (-errno);
+
+ return (ret);
+}
+
+/*
* Implementation of Linux readv() and writev() system calls.
*
* The Linux system calls differ from the Solaris system calls in a few key
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 03eaff46bc..d9534848d5 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
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1158,7 +1158,7 @@ static struct lx_sysent sysents[] = {
{"sigqueueinfo", NULL, NOSYS_UNDOC, 0}, /* 178 */
{"rt_sigsuspend", lx_rt_sigsuspend, 0, 2}, /* 179 */
{"pread64", lx_pread64, 0, 5}, /* 180 */
- {"pwrite64", pwrite64, SYS_PASSTHRU, 5}, /* 181 */
+ {"pwrite64", lx_pwrite64, 0, 5}, /* 181 */
{"chown16", lx_chown16, 0, 3}, /* 182 */
{"getcwd", lx_getcwd, 0, 2}, /* 183 */
{"capget", NULL, NOSYS_NO_EQUIV, 0}, /* 184 */
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 5c52b1acec..fde32fe7bc 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
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -62,6 +62,7 @@ extern int lx_read(uintptr_t, uintptr_t, uintptr_t);
extern int lx_readv(uintptr_t, uintptr_t, uintptr_t);
extern int lx_writev(uintptr_t, uintptr_t, uintptr_t);
extern int lx_pread64(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+extern int lx_pwrite64(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
extern int lx_socketcall(uintptr_t, uintptr_t);
extern int lx_select(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);