summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2014-07-29 18:22:51 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2014-07-29 18:22:51 +0000
commit6244e16c8431c324fd9e88e35ed1159d63e809e5 (patch)
tree4430cfeeb666825472ea9a44000876dd86033fea /usr/src
parent661eda313cdba2cfb6de9f1825ce72ac87780759 (diff)
downloadillumos-joyent-6244e16c8431c324fd9e88e35ed1159d63e809e5.tar.gz
OS-3262 ltp ftruncate returns wrong errno
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/truncate.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/truncate.c b/usr/src/lib/brand/lx/lx_brand/common/truncate.c
index 81fdfbac35..8f1e318d8c 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/truncate.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/truncate.c
@@ -22,12 +22,12 @@
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2014 Joyent, Inc. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <errno.h>
#include <unistd.h>
+#include <fcntl.h>
#include <sys/lx_types.h>
#include <sys/lx_misc.h>
@@ -45,7 +45,27 @@ lx_truncate(uintptr_t path, uintptr_t length)
int
lx_ftruncate(uintptr_t fd, uintptr_t length)
{
- return (ftruncate((int)fd, (off_t)length) == 0 ? 0 : -errno);
+ int r;
+
+ r = ftruncate((int)fd, (off_t)length);
+ /*
+ * On Linux, truncating a file opened read-only returns EINVAL whereas
+ * Illumos returns EBADF.
+ */
+ if (r != 0) {
+ if (errno == EBADF) {
+ int mode;
+
+ if ((mode = fcntl(fd, F_GETFL, 0)) != -1 &&
+ (mode & O_ACCMODE) == O_RDONLY)
+ r = -EINVAL;
+ else
+ r = -EBADF; /* keep existing errno */
+ } else {
+ r = -errno;
+ }
+ }
+ return (r);
}
int
@@ -58,6 +78,26 @@ lx_truncate64(uintptr_t path, uintptr_t length_lo, uintptr_t length_hi)
int
lx_ftruncate64(uintptr_t fd, uintptr_t length_lo, uintptr_t length_hi)
{
- return (ftruncate64((int)fd,
- LX_32TO64(length_lo, length_hi)) == 0 ? 0 : -errno);
+ int r;
+
+ r = ftruncate64((int)fd, LX_32TO64(length_lo, length_hi));
+ /*
+ * On Linux, truncating a file opened read-only returns EINVAL whereas
+ * Illumos returns EBADF.
+ */
+ if (r != 0) {
+ if (errno == EBADF) {
+ int mode;
+
+ if ((mode = fcntl(fd, F_GETFL, 0)) != -1 &&
+ (mode & O_ACCMODE) == O_RDONLY)
+ r = -EINVAL;
+ else
+ r = -EBADF; /* keep existing errno */
+ } else {
+ r = -errno;
+ }
+ }
+
+ return (r);
}