| /* | |
| * tools/testing/selftests/kvm/lib/io.c | |
| * | |
| * Copyright (C) 2018, Google LLC. | |
| * | |
| * This work is licensed under the terms of the GNU GPL, version 2. | |
| */ | |
| #include "test_util.h" | |
| /* Test Write | |
| * | |
| * A wrapper for write(2), that automatically handles the following | |
| * special conditions: | |
| * | |
| * + Interrupted system call (EINTR) | |
| * + Write of less than requested amount | |
| * + Non-block return (EAGAIN) | |
| * | |
| * For each of the above, an additional write is performed to automatically | |
| * continue writing the requested data. | |
| * There are also many cases where write(2) can return an unexpected | |
| * error (e.g. EIO). Such errors cause a TEST_ASSERT failure. | |
| * | |
| * Note, for function signature compatibility with write(2), this function | |
| * returns the number of bytes written, but that value will always be equal | |
| * to the number of requested bytes. All other conditions in this and | |
| * future enhancements to this function either automatically issue another | |
| * write(2) or cause a TEST_ASSERT failure. | |
| * | |
| * Args: | |
| * fd - Opened file descriptor to file to be written. | |
| * count - Number of bytes to write. | |
| * | |
| * Output: | |
| * buf - Starting address of data to be written. | |
| * | |
| * Return: | |
| * On success, number of bytes written. | |
| * On failure, a TEST_ASSERT failure is caused. | |
| */ | |
| ssize_t test_write(int fd, const void *buf, size_t count) | |
| { | |
| ssize_t rc; | |
| ssize_t num_written = 0; | |
| size_t num_left = count; | |
| const char *ptr = buf; | |
| /* Note: Count of zero is allowed (see "RETURN VALUE" portion of | |
| * write(2) manpage for details. | |
| */ | |
| TEST_ASSERT(count >= 0, "Unexpected count, count: %li", count); | |
| do { | |
| rc = write(fd, ptr, num_left); | |
| switch (rc) { | |
| case -1: | |
| TEST_ASSERT(errno == EAGAIN || errno == EINTR, | |
| "Unexpected write failure,\n" | |
| " rc: %zi errno: %i", rc, errno); | |
| continue; | |
| case 0: | |
| TEST_ASSERT(false, "Unexpected EOF,\n" | |
| " rc: %zi num_written: %zi num_left: %zu", | |
| rc, num_written, num_left); | |
| break; | |
| default: | |
| TEST_ASSERT(rc >= 0, "Unexpected ret from write,\n" | |
| " rc: %zi errno: %i", rc, errno); | |
| num_written += rc; | |
| num_left -= rc; | |
| ptr += rc; | |
| break; | |
| } | |
| } while (num_written < count); | |
| return num_written; | |
| } | |
| /* Test Read | |
| * | |
| * A wrapper for read(2), that automatically handles the following | |
| * special conditions: | |
| * | |
| * + Interrupted system call (EINTR) | |
| * + Read of less than requested amount | |
| * + Non-block return (EAGAIN) | |
| * | |
| * For each of the above, an additional read is performed to automatically | |
| * continue reading the requested data. | |
| * There are also many cases where read(2) can return an unexpected | |
| * error (e.g. EIO). Such errors cause a TEST_ASSERT failure. Note, | |
| * it is expected that the file opened by fd at the current file position | |
| * contains at least the number of requested bytes to be read. A TEST_ASSERT | |
| * failure is produced if an End-Of-File condition occurs, before all the | |
| * data is read. It is the callers responsibility to assure that sufficient | |
| * data exists. | |
| * | |
| * Note, for function signature compatibility with read(2), this function | |
| * returns the number of bytes read, but that value will always be equal | |
| * to the number of requested bytes. All other conditions in this and | |
| * future enhancements to this function either automatically issue another | |
| * read(2) or cause a TEST_ASSERT failure. | |
| * | |
| * Args: | |
| * fd - Opened file descriptor to file to be read. | |
| * count - Number of bytes to read. | |
| * | |
| * Output: | |
| * buf - Starting address of where to write the bytes read. | |
| * | |
| * Return: | |
| * On success, number of bytes read. | |
| * On failure, a TEST_ASSERT failure is caused. | |
| */ | |
| ssize_t test_read(int fd, void *buf, size_t count) | |
| { | |
| ssize_t rc; | |
| ssize_t num_read = 0; | |
| size_t num_left = count; | |
| char *ptr = buf; | |
| /* Note: Count of zero is allowed (see "If count is zero" portion of | |
| * read(2) manpage for details. | |
| */ | |
| TEST_ASSERT(count >= 0, "Unexpected count, count: %li", count); | |
| do { | |
| rc = read(fd, ptr, num_left); | |
| switch (rc) { | |
| case -1: | |
| TEST_ASSERT(errno == EAGAIN || errno == EINTR, | |
| "Unexpected read failure,\n" | |
| " rc: %zi errno: %i", rc, errno); | |
| break; | |
| case 0: | |
| TEST_ASSERT(false, "Unexpected EOF,\n" | |
| " rc: %zi num_read: %zi num_left: %zu", | |
| rc, num_read, num_left); | |
| break; | |
| default: | |
| TEST_ASSERT(rc > 0, "Unexpected ret from read,\n" | |
| " rc: %zi errno: %i", rc, errno); | |
| num_read += rc; | |
| num_left -= rc; | |
| ptr += rc; | |
| break; | |
| } | |
| } while (num_read < count); | |
| return num_read; | |
| } |