1 #include "kvm/read-write.h" 2 3 #include <sys/types.h> 4 #include <unistd.h> 5 #include <string.h> 6 #include <errno.h> 7 8 /* Same as read(2) except that this function never returns EAGAIN or EINTR. */ 9 ssize_t xread(int fd, void *buf, size_t count) 10 { 11 ssize_t nr; 12 13 restart: 14 nr = read(fd, buf, count); 15 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR))) 16 goto restart; 17 18 return nr; 19 } 20 21 /* Same as write(2) except that this function never returns EAGAIN or EINTR. */ 22 ssize_t xwrite(int fd, const void *buf, size_t count) 23 { 24 ssize_t nr; 25 26 restart: 27 nr = write(fd, buf, count); 28 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR))) 29 goto restart; 30 31 return nr; 32 } 33 34 ssize_t read_in_full(int fd, void *buf, size_t count) 35 { 36 ssize_t total = 0; 37 char *p = buf; 38 39 while (count > 0) { 40 ssize_t nr; 41 42 nr = xread(fd, p, count); 43 if (nr <= 0) { 44 if (total > 0) 45 return total; 46 47 return -1; 48 } 49 50 count -= nr; 51 total += nr; 52 p += nr; 53 } 54 55 return total; 56 } 57 58 ssize_t write_in_full(int fd, const void *buf, size_t count) 59 { 60 const char *p = buf; 61 ssize_t total = 0; 62 63 while (count > 0) { 64 ssize_t nr; 65 66 nr = xwrite(fd, p, count); 67 if (nr < 0) 68 return -1; 69 if (nr == 0) { 70 errno = ENOSPC; 71 return -1; 72 } 73 count -= nr; 74 total += nr; 75 p += nr; 76 } 77 78 return total; 79 } 80 81 /* Same as pread(2) except that this function never returns EAGAIN or EINTR. */ 82 ssize_t xpread(int fd, void *buf, size_t count, off_t offset) 83 { 84 ssize_t nr; 85 86 restart: 87 nr = pread(fd, buf, count, offset); 88 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR))) 89 goto restart; 90 91 return nr; 92 } 93 94 /* Same as pwrite(2) except that this function never returns EAGAIN or EINTR. */ 95 ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset) 96 { 97 ssize_t nr; 98 99 restart: 100 nr = pwrite(fd, buf, count, offset); 101 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR))) 102 goto restart; 103 104 return nr; 105 } 106 107 ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset) 108 { 109 ssize_t total = 0; 110 char *p = buf; 111 112 while (count > 0) { 113 ssize_t nr; 114 115 nr = xpread(fd, p, count, offset); 116 if (nr <= 0) { 117 if (total > 0) 118 return total; 119 120 return -1; 121 } 122 123 count -= nr; 124 total += nr; 125 p += nr; 126 offset += nr; 127 } 128 129 return total; 130 } 131 132 ssize_t pwrite_in_full(int fd, const void *buf, size_t count, off_t offset) 133 { 134 const char *p = buf; 135 ssize_t total = 0; 136 137 while (count > 0) { 138 ssize_t nr; 139 140 nr = xpwrite(fd, p, count, offset); 141 if (nr < 0) 142 return -1; 143 if (nr == 0) { 144 errno = ENOSPC; 145 return -1; 146 } 147 count -= nr; 148 total += nr; 149 p += nr; 150 offset += nr; 151 } 152 153 return total; 154 } 155