// SPDX-License-Identifier: GPL-2.0-only1/*2* tools/testing/selftests/kvm/lib/io.c3*4* Copyright (C) 2018, Google LLC.5*/67#include "test_util.h"89/* Test Write10*11* A wrapper for write(2), that automatically handles the following12* special conditions:13*14* + Interrupted system call (EINTR)15* + Write of less than requested amount16* + Non-block return (EAGAIN)17*18* For each of the above, an additional write is performed to automatically19* continue writing the requested data.20* There are also many cases where write(2) can return an unexpected21* error (e.g. EIO). Such errors cause a TEST_ASSERT failure.22*23* Note, for function signature compatibility with write(2), this function24* returns the number of bytes written, but that value will always be equal25* to the number of requested bytes. All other conditions in this and26* future enhancements to this function either automatically issue another27* write(2) or cause a TEST_ASSERT failure.28*29* Args:30* fd - Opened file descriptor to file to be written.31* count - Number of bytes to write.32*33* Output:34* buf - Starting address of data to be written.35*36* Return:37* On success, number of bytes written.38* On failure, a TEST_ASSERT failure is caused.39*/40ssize_t test_write(int fd, const void *buf, size_t count)41{42ssize_t rc;43ssize_t num_written = 0;44size_t num_left = count;45const char *ptr = buf;4647/* Note: Count of zero is allowed (see "RETURN VALUE" portion of48* write(2) manpage for details.49*/50TEST_ASSERT(count >= 0, "Unexpected count, count: %li", count);5152do {53rc = write(fd, ptr, num_left);5455switch (rc) {56case -1:57TEST_ASSERT(errno == EAGAIN || errno == EINTR,58"Unexpected write failure,\n"59" rc: %zi errno: %i", rc, errno);60continue;6162case 0:63TEST_FAIL("Unexpected EOF,\n"64" rc: %zi num_written: %zi num_left: %zu",65rc, num_written, num_left);66break;6768default:69TEST_ASSERT(rc >= 0, "Unexpected ret from write,\n"70" rc: %zi errno: %i", rc, errno);71num_written += rc;72num_left -= rc;73ptr += rc;74break;75}76} while (num_written < count);7778return num_written;79}8081/* Test Read82*83* A wrapper for read(2), that automatically handles the following84* special conditions:85*86* + Interrupted system call (EINTR)87* + Read of less than requested amount88* + Non-block return (EAGAIN)89*90* For each of the above, an additional read is performed to automatically91* continue reading the requested data.92* There are also many cases where read(2) can return an unexpected93* error (e.g. EIO). Such errors cause a TEST_ASSERT failure. Note,94* it is expected that the file opened by fd at the current file position95* contains at least the number of requested bytes to be read. A TEST_ASSERT96* failure is produced if an End-Of-File condition occurs, before all the97* data is read. It is the callers responsibility to assure that sufficient98* data exists.99*100* Note, for function signature compatibility with read(2), this function101* returns the number of bytes read, but that value will always be equal102* to the number of requested bytes. All other conditions in this and103* future enhancements to this function either automatically issue another104* read(2) or cause a TEST_ASSERT failure.105*106* Args:107* fd - Opened file descriptor to file to be read.108* count - Number of bytes to read.109*110* Output:111* buf - Starting address of where to write the bytes read.112*113* Return:114* On success, number of bytes read.115* On failure, a TEST_ASSERT failure is caused.116*/117ssize_t test_read(int fd, void *buf, size_t count)118{119ssize_t rc;120ssize_t num_read = 0;121size_t num_left = count;122char *ptr = buf;123124/* Note: Count of zero is allowed (see "If count is zero" portion of125* read(2) manpage for details.126*/127TEST_ASSERT(count >= 0, "Unexpected count, count: %li", count);128129do {130rc = read(fd, ptr, num_left);131132switch (rc) {133case -1:134TEST_ASSERT(errno == EAGAIN || errno == EINTR,135"Unexpected read failure,\n"136" rc: %zi errno: %i", rc, errno);137break;138139case 0:140TEST_FAIL("Unexpected EOF,\n"141" rc: %zi num_read: %zi num_left: %zu",142rc, num_read, num_left);143break;144145default:146TEST_ASSERT(rc > 0, "Unexpected ret from read,\n"147" rc: %zi errno: %i", rc, errno);148num_read += rc;149num_left -= rc;150ptr += rc;151break;152}153} while (num_read < count);154155return num_read;156}157158159