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 } 159