summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2001-08-16 22:20:06 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2001-08-16 22:20:06 +0000
commitdfd218d5fe18569de44bbd00f75773c4f2fe8316 (patch)
treed53da8a83b02066a06ab3169eff2afc80cd938d0
parent3a5fec8fefe59cd53f0c0e6d260162b1819e92f6 (diff)
downloadrtems-dfd218d5fe18569de44bbd00f75773c4f2fe8316.tar.bz2
2001-08-16 Joel Sherrill <joel@OARcorp.com>
* libc/lseek.c: Modified after discussion with Eugeny S. Mints <jack@oktet.ru> to correct the behavior. There were two mistakes. First, iop->offset was incorrectly set for SEEK_END. Second, iop->offset should be left unmodified if there are errors. This modification attempts to fix both situations.
-rw-r--r--c/src/exec/libcsupport/src/lseek.c32
-rw-r--r--c/src/lib/ChangeLog8
-rw-r--r--c/src/lib/libc/lseek.c32
-rw-r--r--cpukit/libcsupport/src/lseek.c32
4 files changed, 86 insertions, 18 deletions
diff --git a/c/src/exec/libcsupport/src/lseek.c b/c/src/exec/libcsupport/src/lseek.c
index 069952ff8e..910b81d231 100644
--- a/c/src/exec/libcsupport/src/lseek.c
+++ b/c/src/exec/libcsupport/src/lseek.c
@@ -26,15 +26,25 @@ off_t lseek(
)
{
rtems_libio_t *iop;
+ off_t old_offset;
+ off_t status;
rtems_libio_check_fd( fd );
iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop);
/*
+ * Check as many errors as possible before touching iop->offset.
+ */
+
+ if ( !iop->handlers->lseek_h )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ /*
* Now process the lseek().
*/
+ old_offset = iop->offset;
switch ( whence ) {
case SEEK_SET:
iop->offset = offset;
@@ -45,18 +55,28 @@ off_t lseek(
break;
case SEEK_END:
- iop->offset = iop->size - offset;
+ iop->offset = iop->size + offset;
break;
default:
- errno = EINVAL;
- return -1;
+ set_errno_and_return_minus_one( EINVAL );
}
- if ( !iop->handlers->lseek_h )
- set_errno_and_return_minus_one( ENOTSUP );
+ /*
+ * At this time, handlers assume iop->offset has the desired
+ * new offset.
+ */
+
+ status = (*iop->handlers->lseek_h)( iop, offset, whence );
+ if ( !status )
+ return 0;
+
+ /*
+ * So if the operation failed, we have to restore iop->offset.
+ */
- return (*iop->handlers->lseek_h)( iop, offset, whence );
+ iop->offset = old_offset;
+ return status;
}
/*
diff --git a/c/src/lib/ChangeLog b/c/src/lib/ChangeLog
index 29727ca717..994617a053 100644
--- a/c/src/lib/ChangeLog
+++ b/c/src/lib/ChangeLog
@@ -1,3 +1,11 @@
+2001-08-16 Joel Sherrill <joel@OARcorp.com>
+
+ * libc/lseek.c: Modified after discussion with Eugeny S. Mints
+ <jack@oktet.ru> to correct the behavior. There were two mistakes.
+ First, iop->offset was incorrectly set for SEEK_END. Second,
+ iop->offset should be left unmodified if there are errors.
+ This modification attempts to fix both situations.
+
2001-08-16 Mike Siers <mikes@poliac.com>
* include/rtems/termiostypes.h, include/sys/ioccom.h:
diff --git a/c/src/lib/libc/lseek.c b/c/src/lib/libc/lseek.c
index 069952ff8e..910b81d231 100644
--- a/c/src/lib/libc/lseek.c
+++ b/c/src/lib/libc/lseek.c
@@ -26,15 +26,25 @@ off_t lseek(
)
{
rtems_libio_t *iop;
+ off_t old_offset;
+ off_t status;
rtems_libio_check_fd( fd );
iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop);
/*
+ * Check as many errors as possible before touching iop->offset.
+ */
+
+ if ( !iop->handlers->lseek_h )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ /*
* Now process the lseek().
*/
+ old_offset = iop->offset;
switch ( whence ) {
case SEEK_SET:
iop->offset = offset;
@@ -45,18 +55,28 @@ off_t lseek(
break;
case SEEK_END:
- iop->offset = iop->size - offset;
+ iop->offset = iop->size + offset;
break;
default:
- errno = EINVAL;
- return -1;
+ set_errno_and_return_minus_one( EINVAL );
}
- if ( !iop->handlers->lseek_h )
- set_errno_and_return_minus_one( ENOTSUP );
+ /*
+ * At this time, handlers assume iop->offset has the desired
+ * new offset.
+ */
+
+ status = (*iop->handlers->lseek_h)( iop, offset, whence );
+ if ( !status )
+ return 0;
+
+ /*
+ * So if the operation failed, we have to restore iop->offset.
+ */
- return (*iop->handlers->lseek_h)( iop, offset, whence );
+ iop->offset = old_offset;
+ return status;
}
/*
diff --git a/cpukit/libcsupport/src/lseek.c b/cpukit/libcsupport/src/lseek.c
index 069952ff8e..910b81d231 100644
--- a/cpukit/libcsupport/src/lseek.c
+++ b/cpukit/libcsupport/src/lseek.c
@@ -26,15 +26,25 @@ off_t lseek(
)
{
rtems_libio_t *iop;
+ off_t old_offset;
+ off_t status;
rtems_libio_check_fd( fd );
iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop);
/*
+ * Check as many errors as possible before touching iop->offset.
+ */
+
+ if ( !iop->handlers->lseek_h )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ /*
* Now process the lseek().
*/
+ old_offset = iop->offset;
switch ( whence ) {
case SEEK_SET:
iop->offset = offset;
@@ -45,18 +55,28 @@ off_t lseek(
break;
case SEEK_END:
- iop->offset = iop->size - offset;
+ iop->offset = iop->size + offset;
break;
default:
- errno = EINVAL;
- return -1;
+ set_errno_and_return_minus_one( EINVAL );
}
- if ( !iop->handlers->lseek_h )
- set_errno_and_return_minus_one( ENOTSUP );
+ /*
+ * At this time, handlers assume iop->offset has the desired
+ * new offset.
+ */
+
+ status = (*iop->handlers->lseek_h)( iop, offset, whence );
+ if ( !status )
+ return 0;
+
+ /*
+ * So if the operation failed, we have to restore iop->offset.
+ */
- return (*iop->handlers->lseek_h)( iop, offset, whence );
+ iop->offset = old_offset;
+ return status;
}
/*