xref: /openbmc/linux/tools/testing/selftests/kvm/lib/io.c (revision 81de3bf3)
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  */
41 ssize_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_ASSERT(false, "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  */
118 ssize_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_ASSERT(false, "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