158 lines
4.3 KiB
C
158 lines
4.3 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* tools/testing/selftests/kvm/lib/io.c
|
|
*
|
|
* Copyright (C) 2018, Google LLC.
|
|
*/
|
|
|
|
#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_FAIL("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_FAIL("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;
|
|
}
|