diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-12-16 13:12:22 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-12-20 10:31:53 +0100 |
commit | 95a57280ebc3996547fccd6065a5652a846d1447 (patch) | |
tree | 9a39803381927d9acf8b426ff995248455b19184 /cpukit/libcsupport/src/readv.c | |
parent | arm/gba: doxygen improvement (diff) | |
download | rtems-95a57280ebc3996547fccd6065a5652a846d1447.tar.bz2 |
libcsupport: Add and use rtems_libio_iovec_eval()
Diffstat (limited to 'cpukit/libcsupport/src/readv.c')
-rw-r--r-- | cpukit/libcsupport/src/readv.c | 88 |
1 files changed, 15 insertions, 73 deletions
diff --git a/cpukit/libcsupport/src/readv.c b/cpukit/libcsupport/src/readv.c index 2ff7f63767..e47f22850a 100644 --- a/cpukit/libcsupport/src/readv.c +++ b/cpukit/libcsupport/src/readv.c @@ -18,11 +18,9 @@ #include "config.h" #endif -#include <sys/types.h> #include <sys/uio.h> #include <rtems/libio_.h> -#include <rtems/seterr.h> /** * readv() - POSIX 1003.1 - Read a Vector @@ -39,86 +37,30 @@ ssize_t readv( { ssize_t total; int v; - int bytes; rtems_libio_t *iop; - bool all_zeros; - rtems_libio_check_fd( fd ); - iop = rtems_libio_iop( fd ); - rtems_libio_check_is_open( iop ); - rtems_libio_check_permissions_with_error( iop, LIBIO_FLAGS_READ, EBADF ); - - /* - * Argument validation on IO vector - */ - if ( !iov ) - rtems_set_errno_and_return_minus_one( EINVAL ); - - if ( iovcnt <= 0 ) - rtems_set_errno_and_return_minus_one( EINVAL ); - - if ( iovcnt > IOV_MAX ) - rtems_set_errno_and_return_minus_one( EINVAL ); - - /* - * OpenGroup says that you are supposed to return EINVAL if the - * sum of the iov_len values in the iov array would overflow a - * ssize_t. - * - * Also we would like to ensure that no IO is performed if there - * are obvious errors in the iovec. So this extra loop ensures - * that we do not do anything if there is an argument error. - */ - - all_zeros = true; - for ( total=0, v=0 ; v < iovcnt ; v++ ) { - ssize_t old; + total = rtems_libio_iovec_eval( fd, iov, iovcnt, LIBIO_FLAGS_READ, &iop ); + if ( total > 0 ) { /* - * iov[v].iov_len cannot be less than 0 because size_t is unsigned. - * So we only check for zero. + * Now process the readv(). */ - if ( iov[v].iov_base == 0 ) - rtems_set_errno_and_return_minus_one( EINVAL ); + total = 0; + for ( v = 0 ; v < iovcnt ; v++ ) { + ssize_t bytes = ( *iop->pathinfo.handlers->read_h )( + iop, + iov[ v ].iov_base, + iov[ v ].iov_len + ); - /* check for wrap */ - old = total; - total += iov[v].iov_len; - if ( total < old ) - rtems_set_errno_and_return_minus_one( EINVAL ); + if ( bytes < 0 ) + return -1; - if ( iov[v].iov_len ) - all_zeros = false; - } + total += bytes; - /* - * A readv with all zeros logically has no effect. Even though - * OpenGroup didn't address this case as they did with writev(), - * we will handle it the same way for symmetry. - */ - if ( all_zeros == true ) { - return 0; - } - - /* - * Now process the readv(). - */ - for ( total=0, v=0 ; v < iovcnt ; v++ ) { - bytes = (*iop->pathinfo.handlers->read_h)( - iop, - iov[v].iov_base, - iov[v].iov_len - ); - - if ( bytes < 0 ) - return -1; - - if ( bytes > 0 ) { - total += bytes; + if ( bytes != iov[ v ].iov_len ) + break; } - - if (bytes != iov[ v ].iov_len) - break; } return total; |