xref: /kvmtool/util/read-write.c (revision c4d7847b220c2cccfc0cf6c4d78da631b3edcd6b)
1*c4d7847bSPekka Enberg #include "kvm/read-write.h"
2*c4d7847bSPekka Enberg 
3*c4d7847bSPekka Enberg #include <sys/types.h>
4*c4d7847bSPekka Enberg #include <unistd.h>
5*c4d7847bSPekka Enberg #include <string.h>
6*c4d7847bSPekka Enberg #include <errno.h>
7*c4d7847bSPekka Enberg 
8*c4d7847bSPekka Enberg /* Same as read(2) except that this function never returns EAGAIN or EINTR. */
9*c4d7847bSPekka Enberg ssize_t xread(int fd, void *buf, size_t count)
10*c4d7847bSPekka Enberg {
11*c4d7847bSPekka Enberg 	ssize_t nr;
12*c4d7847bSPekka Enberg 
13*c4d7847bSPekka Enberg restart:
14*c4d7847bSPekka Enberg 	nr = read(fd, buf, count);
15*c4d7847bSPekka Enberg 	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
16*c4d7847bSPekka Enberg 		goto restart;
17*c4d7847bSPekka Enberg 
18*c4d7847bSPekka Enberg 	return nr;
19*c4d7847bSPekka Enberg }
20*c4d7847bSPekka Enberg 
21*c4d7847bSPekka Enberg /* Same as write(2) except that this function never returns EAGAIN or EINTR. */
22*c4d7847bSPekka Enberg ssize_t xwrite(int fd, const void *buf, size_t count)
23*c4d7847bSPekka Enberg {
24*c4d7847bSPekka Enberg 	ssize_t nr;
25*c4d7847bSPekka Enberg 
26*c4d7847bSPekka Enberg restart:
27*c4d7847bSPekka Enberg 	nr = write(fd, buf, count);
28*c4d7847bSPekka Enberg 	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
29*c4d7847bSPekka Enberg 		goto restart;
30*c4d7847bSPekka Enberg 
31*c4d7847bSPekka Enberg 	return nr;
32*c4d7847bSPekka Enberg }
33*c4d7847bSPekka Enberg 
34*c4d7847bSPekka Enberg ssize_t read_in_full(int fd, void *buf, size_t count)
35*c4d7847bSPekka Enberg {
36*c4d7847bSPekka Enberg 	ssize_t total = 0;
37*c4d7847bSPekka Enberg 	char *p = buf;
38*c4d7847bSPekka Enberg 
39*c4d7847bSPekka Enberg 	while (count > 0) {
40*c4d7847bSPekka Enberg 		ssize_t nr;
41*c4d7847bSPekka Enberg 
42*c4d7847bSPekka Enberg 		nr = xread(fd, p, count);
43*c4d7847bSPekka Enberg 		if (nr <= 0) {
44*c4d7847bSPekka Enberg 			if (total > 0)
45*c4d7847bSPekka Enberg 				return total;
46*c4d7847bSPekka Enberg 
47*c4d7847bSPekka Enberg 			return -1;
48*c4d7847bSPekka Enberg 		}
49*c4d7847bSPekka Enberg 
50*c4d7847bSPekka Enberg 		count -= nr;
51*c4d7847bSPekka Enberg 		total += nr;
52*c4d7847bSPekka Enberg 		p += nr;
53*c4d7847bSPekka Enberg 	}
54*c4d7847bSPekka Enberg 
55*c4d7847bSPekka Enberg 	return total;
56*c4d7847bSPekka Enberg }
57*c4d7847bSPekka Enberg 
58*c4d7847bSPekka Enberg ssize_t write_in_full(int fd, const void *buf, size_t count)
59*c4d7847bSPekka Enberg {
60*c4d7847bSPekka Enberg 	const char *p = buf;
61*c4d7847bSPekka Enberg 	ssize_t total = 0;
62*c4d7847bSPekka Enberg 
63*c4d7847bSPekka Enberg 	while (count > 0) {
64*c4d7847bSPekka Enberg 		ssize_t nr;
65*c4d7847bSPekka Enberg 
66*c4d7847bSPekka Enberg 		nr = xwrite(fd, p, count);
67*c4d7847bSPekka Enberg 		if (nr < 0)
68*c4d7847bSPekka Enberg 			return -1;
69*c4d7847bSPekka Enberg 		if (nr == 0) {
70*c4d7847bSPekka Enberg 			errno = ENOSPC;
71*c4d7847bSPekka Enberg 			return -1;
72*c4d7847bSPekka Enberg 		}
73*c4d7847bSPekka Enberg 		count -= nr;
74*c4d7847bSPekka Enberg 		total += nr;
75*c4d7847bSPekka Enberg 		p += nr;
76*c4d7847bSPekka Enberg 	}
77*c4d7847bSPekka Enberg 
78*c4d7847bSPekka Enberg 	return total;
79*c4d7847bSPekka Enberg }
80