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.
This commit is contained in:
Joel Sherrill
2001-08-16 22:15:35 +00:00
parent b3a6713265
commit cbdb14497c

View File

@@ -22,15 +22,25 @@ off_t lseek(
) )
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
off_t old_offset;
off_t status;
rtems_libio_check_fd( fd ); rtems_libio_check_fd( fd );
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* Check as many errors as possible before touching iop->offset.
*/
if ( !iop->handlers->lseek )
set_errno_and_return_minus_one( ENOTSUP );
/* /*
* Now process the lseek(). * Now process the lseek().
*/ */
old_offset = iop->offset;
switch ( whence ) { switch ( whence ) {
case SEEK_SET: case SEEK_SET:
iop->offset = offset; iop->offset = offset;
@@ -41,18 +51,28 @@ off_t lseek(
break; break;
case SEEK_END: case SEEK_END:
iop->offset = iop->size - offset; iop->offset = iop->size + offset;
break; break;
default: default:
errno = EINVAL; set_errno_and_return_minus_one( EINVAL );
return -1;
} }
if ( !iop->handlers->lseek ) /*
set_errno_and_return_minus_one( ENOTSUP ); * At this time, handlers assume iop->offset has the desired
* new offset.
*/
return (*iop->handlers->lseek)( iop, offset, whence ); status = (*iop->handlers->lseek)( iop, offset, whence );
if ( !status )
return 0;
/*
* So if the operation failed, we have to restore iop->offset.
*/
iop->offset = old_offset;
return status;
} }
/* /*