ssize_t read( int fd, void *buffer, size_t count ) { ssize_t rc; rtems_libio_t *iop; rtems_libio_check_fd( fd ); iop = rtems_libio_iop( fd ); rtems_libio_check_is_open( iop ); rtems_libio_check_buffer( buffer ); rtems_libio_check_count( count ); rtems_libio_check_permissions_with_error( iop, LIBIO_FLAGS_READ, EBADF ); /* * Now process the read(). */ if ( !iop->handlers->read_h ) rtems_set_errno_and_return_minus_one( ENOTSUP ); rc = (*iop->handlers->read_h)( iop, buffer, count ); if ( rc > 0 ) iop->offset += rc; return rc; }
ssize_t write( int fd, const void *buffer, size_t count ) { ssize_t rc; rtems_libio_t *iop; rtems_libio_check_fd( fd ); iop = rtems_libio_iop( fd ); rtems_libio_check_is_open( iop ); rtems_libio_check_buffer( buffer ); rtems_libio_check_count( count ); rtems_libio_check_permissions_with_error( iop, LIBIO_FLAGS_WRITE, EBADF ); /* * Now process the write() request. */ rc = (*iop->pathinfo.handlers->write_h)( iop, buffer, count ); if ( rc > 0 ) iop->offset += rc; return rc; }
int fdatasync( int fd ) { rtems_libio_t *iop; 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_WRITE, EBADF ); /* * Now process the fdatasync(). */ return (*iop->pathinfo.handlers->fdatasync_h)( iop ); }
/** * POSIX 1003.1b 6.4.1 - Read From a File */ ssize_t read( int fd, void *buffer, size_t count ) { rtems_libio_t *iop; rtems_libio_check_fd( fd ); iop = rtems_libio_iop( fd ); rtems_libio_check_is_open( iop ); rtems_libio_check_buffer( buffer ); rtems_libio_check_count( count ); rtems_libio_check_permissions_with_error( iop, LIBIO_FLAGS_READ, EBADF ); /* * Now process the read(). */ return (*iop->pathinfo.handlers->read_h)( iop, buffer, count ); }
ssize_t writev( int fd, const struct iovec *iov, int iovcnt ) { ssize_t total; int v; int bytes; rtems_libio_t *iop; ssize_t old; 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_WRITE, 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 ); if ( !iop->handlers->write_h ) rtems_set_errno_and_return_minus_one( ENOTSUP ); /* * 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. * * In addition,the OpenGroup specification says that if all the * iov_len entries are zero, then the call has no effect. So * this loop does that check as well and sets "all-zero" appropriately. * The variable "all_zero" is used as an early exit point before * entering the write loop. */ all_zeros = true; for ( old=0, total=0, v=0 ; v < iovcnt ; v++ ) { if ( !iov[v].iov_base ) rtems_set_errno_and_return_minus_one( EINVAL ); if ( iov[v].iov_len < 0 ) rtems_set_errno_and_return_minus_one( EINVAL ); if ( iov[v].iov_len ) all_zeros = false; /* check for wrap */ old = total; total += iov[v].iov_len; if ( total < old || total > SSIZE_MAX ) rtems_set_errno_and_return_minus_one( EINVAL ); } /* * A writev with all zeros is supposed to have no effect per OpenGroup. */ if ( all_zeros == true ) { return 0; } /* * Now process the writev(). */ for ( total=0, v=0 ; v < iovcnt ; v++ ) { /* all zero lengths has no effect */ if ( iov[v].iov_len == 0 ) continue; bytes = (*iop->handlers->write_h)( iop, iov[v].iov_base, iov[v].iov_len ); if ( bytes < 0 ) return -1; if ( bytes > 0 ) { iop->offset += bytes; total += bytes; } if (bytes != iov[ v ].iov_len) break; } return total; }
ssize_t readv( int fd, const struct iovec *iov, int iovcnt ) { 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; /* * iov[v].iov_len cannot be less than 0 because size_t is unsigned. * So we only check for zero. */ if ( iov[v].iov_base == 0 ) rtems_set_errno_and_return_minus_one( EINVAL ); /* check for wrap */ old = total; total += iov[v].iov_len; if ( total < old ) rtems_set_errno_and_return_minus_one( EINVAL ); if ( iov[v].iov_len ) all_zeros = false; } /* * 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 ) { iop->offset += bytes; total += bytes; } if (bytes != iov[ v ].iov_len) break; } return total; }