1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * tools/testing/selftests/kvm/lib/io.c
4 *
5 * Copyright (C) 2018, Google LLC.
6 */
7
8#include "test_util.h"
9
10/* Test Write
11 *
12 * A wrapper for write(2), that automatically handles the following
13 * special conditions:
14 *
15 *   + Interrupted system call (EINTR)
16 *   + Write of less than requested amount
17 *   + Non-block return (EAGAIN)
18 *
19 * For each of the above, an additional write is performed to automatically
20 * continue writing the requested data.
21 * There are also many cases where write(2) can return an unexpected
22 * error (e.g. EIO).  Such errors cause a TEST_ASSERT failure.
23 *
24 * Note, for function signature compatibility with write(2), this function
25 * returns the number of bytes written, but that value will always be equal
26 * to the number of requested bytes.  All other conditions in this and
27 * future enhancements to this function either automatically issue another
28 * write(2) or cause a TEST_ASSERT failure.
29 *
30 * Args:
31 *  fd    - Opened file descriptor to file to be written.
32 *  count - Number of bytes to write.
33 *
34 * Output:
35 *  buf   - Starting address of data to be written.
36 *
37 * Return:
38 *  On success, number of bytes written.
39 *  On failure, a TEST_ASSERT failure is caused.
40 */
41ssize_t test_write(int fd, const void *buf, size_t count)
42{
43	ssize_t rc;
44	ssize_t num_written = 0;
45	size_t num_left = count;
46	const char *ptr = buf;
47
48	/* Note: Count of zero is allowed (see "RETURN VALUE" portion of
49	 * write(2) manpage for details.
50	 */
51	TEST_ASSERT(count >= 0, "Unexpected count, count: %li", count);
52
53	do {
54		rc = write(fd, ptr, num_left);
55
56		switch (rc) {
57		case -1:
58			TEST_ASSERT(errno == EAGAIN || errno == EINTR,
59				    "Unexpected write failure,\n"
60				    "  rc: %zi errno: %i", rc, errno);
61			continue;
62
63		case 0:
64			TEST_FAIL("Unexpected EOF,\n"
65				  "  rc: %zi num_written: %zi num_left: %zu",
66				  rc, num_written, num_left);
67			break;
68
69		default:
70			TEST_ASSERT(rc >= 0, "Unexpected ret from write,\n"
71				"  rc: %zi errno: %i", rc, errno);
72			num_written += rc;
73			num_left -= rc;
74			ptr += rc;
75			break;
76		}
77	} while (num_written < count);
78
79	return num_written;
80}
81
82/* Test Read
83 *
84 * A wrapper for read(2), that automatically handles the following
85 * special conditions:
86 *
87 *   + Interrupted system call (EINTR)
88 *   + Read of less than requested amount
89 *   + Non-block return (EAGAIN)
90 *
91 * For each of the above, an additional read is performed to automatically
92 * continue reading the requested data.
93 * There are also many cases where read(2) can return an unexpected
94 * error (e.g. EIO).  Such errors cause a TEST_ASSERT failure.  Note,
95 * it is expected that the file opened by fd at the current file position
96 * contains at least the number of requested bytes to be read.  A TEST_ASSERT
97 * failure is produced if an End-Of-File condition occurs, before all the
98 * data is read.  It is the callers responsibility to assure that sufficient
99 * data exists.
100 *
101 * Note, for function signature compatibility with read(2), this function
102 * returns the number of bytes read, but that value will always be equal
103 * to the number of requested bytes.  All other conditions in this and
104 * future enhancements to this function either automatically issue another
105 * read(2) or cause a TEST_ASSERT failure.
106 *
107 * Args:
108 *  fd    - Opened file descriptor to file to be read.
109 *  count - Number of bytes to read.
110 *
111 * Output:
112 *  buf   - Starting address of where to write the bytes read.
113 *
114 * Return:
115 *  On success, number of bytes read.
116 *  On failure, a TEST_ASSERT failure is caused.
117 */
118ssize_t test_read(int fd, void *buf, size_t count)
119{
120	ssize_t rc;
121	ssize_t num_read = 0;
122	size_t num_left = count;
123	char *ptr = buf;
124
125	/* Note: Count of zero is allowed (see "If count is zero" portion of
126	 * read(2) manpage for details.
127	 */
128	TEST_ASSERT(count >= 0, "Unexpected count, count: %li", count);
129
130	do {
131		rc = read(fd, ptr, num_left);
132
133		switch (rc) {
134		case -1:
135			TEST_ASSERT(errno == EAGAIN || errno == EINTR,
136				    "Unexpected read failure,\n"
137				    "  rc: %zi errno: %i", rc, errno);
138			break;
139
140		case 0:
141			TEST_FAIL("Unexpected EOF,\n"
142				  "   rc: %zi num_read: %zi num_left: %zu",
143				  rc, num_read, num_left);
144			break;
145
146		default:
147			TEST_ASSERT(rc > 0, "Unexpected ret from read,\n"
148				    "  rc: %zi errno: %i", rc, errno);
149			num_read += rc;
150			num_left -= rc;
151			ptr += rc;
152			break;
153		}
154	} while (num_read < count);
155
156	return num_read;
157}
158