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