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