diff options
Diffstat (limited to 'cpukit/libcsupport')
-rw-r--r-- | cpukit/libcsupport/include/rtems/libio.h | 50 | ||||
-rw-r--r-- | cpukit/libcsupport/src/lseek.c | 54 |
2 files changed, 46 insertions, 58 deletions
diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h index 04ca52c4aa..a740a408f0 100644 --- a/cpukit/libcsupport/include/rtems/libio.h +++ b/cpukit/libcsupport/include/rtems/libio.h @@ -849,8 +849,9 @@ typedef int (*rtems_filesystem_ioctl_t)( * @retval non-negative The new offset from the beginning of the file. * @retval -1 An error occured. The errno is set to indicate the error. * - * @see rtems_filesystem_default_lseek() and - * rtems_filesystem_default_lseek_success(). + * @see rtems_filesystem_default_lseek(), + * rtems_filesystem_default_lseek_file(), and + * rtems_filesystem_default_lseek_directory(). */ typedef off_t (*rtems_filesystem_lseek_t)( rtems_libio_t *iop, @@ -1026,11 +1027,51 @@ off_t rtems_filesystem_default_lseek( ); /** + * @brief An offset 0 with a whence of SEEK_SET will perform a directory rewind + * operation. + * + * This function has no protection against concurrent access. + * + * @retval -1 The offset is not zero or the whence is not SEEK_SET. + * @retval 0 Successful rewind operation. + * + * @see rtems_filesystem_lseek_t. + */ +off_t rtems_filesystem_default_lseek_directory( + rtems_libio_t *iop, + off_t offset, + int whence +); + +/** + * @brief Default lseek() handler for files. + * + * The fstat() handler will be used to obtain the file size in case whence is + * SEEK_END. + * + * This function has no protection against concurrent access. + * + * @retval -1 An error occured. In case an integer overflow occured, then the + * errno will be set to EOVERFLOW. In case the new offset is negative, then + * the errno will be set to EINVAL. In case the whence is SEEK_END and the + * fstat() handler to obtain the current file size returned an error status, + * then the errno will be set by the fstat() handler. + * @retval offset The new offset. + * + * @see rtems_filesystem_lseek_t. + */ +off_t rtems_filesystem_default_lseek_file( + rtems_libio_t *iop, + off_t offset, + int whence +); + +/** * @retval 0 Always. * * @see rtems_filesystem_lseek_t. */ -off_t rtems_filesystem_default_lseek_success( +off_t rtems_filesystem_default_lseek_file( rtems_libio_t *iop, off_t offset, int whence @@ -1157,11 +1198,10 @@ extern const rtems_filesystem_limits_and_options_t * It will be indexed by 'fd'. * * @todo Should really have a separate per/file data structure that this points - * to (eg: size, offset, driver, pathname should be in that) + * to (eg: offset, driver, pathname should be in that) */ struct rtems_libio_tt { rtems_driver_name_t *driver; - off_t size; /* size of file */ off_t offset; /* current offset into file */ uint32_t flags; rtems_filesystem_location_info_t pathinfo; diff --git a/cpukit/libcsupport/src/lseek.c b/cpukit/libcsupport/src/lseek.c index 7c1f76b36b..fa18db33f4 100644 --- a/cpukit/libcsupport/src/lseek.c +++ b/cpukit/libcsupport/src/lseek.c @@ -21,65 +21,13 @@ off_t lseek( int fd, off_t offset, int whence ) { - off_t rv = 0; rtems_libio_t *iop; - off_t reference_offset; - off_t old_offset; - off_t new_offset; rtems_libio_check_fd( fd ); iop = rtems_libio_iop( fd ); rtems_libio_check_is_open(iop); - old_offset = iop->offset; - switch ( whence ) { - case SEEK_SET: - reference_offset = 0; - break; - case SEEK_CUR: - reference_offset = old_offset; - break; - case SEEK_END: - reference_offset = iop->size; - break; - default: - errno = EINVAL; - rv = (off_t) -1; - break; - } - new_offset = reference_offset + offset; - - if ( rv == 0 ) { - if ( - (reference_offset >= 0 && new_offset >= offset) - || (reference_offset < 0 && new_offset <= offset) - ) { - switch ( rtems_filesystem_node_type( &iop->pathinfo ) ) { - case RTEMS_FILESYSTEM_DIRECTORY: - case RTEMS_FILESYSTEM_MEMORY_FILE: - if ( new_offset < 0 ) { - errno = EINVAL; - rv = (off_t) -1; - } - break; - default: - break; - } - - if ( rv == 0 ) { - iop->offset = new_offset; - rv = (*iop->pathinfo.handlers->lseek_h)( iop, offset, whence ); - if ( rv == (off_t) -1 ) { - iop->offset = old_offset; - } - } - } else { - errno = EOVERFLOW; - rv = (off_t) -1; - } - } - - return rv; + return (*iop->pathinfo.handlers->lseek_h)( iop, offset, whence ); } /* |