1 #include "kvm/read-write.h"
9 /* Same as read(2) except that this function never returns EAGAIN or EINTR. */
10 ssize_t xread(int fd, void *buf, size_t count)
15 nr = read(fd, buf, count);
16 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
22 /* Same as write(2) except that this function never returns EAGAIN or EINTR. */
23 ssize_t xwrite(int fd, const void *buf, size_t count)
28 nr = write(fd, buf, count);
29 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
35 ssize_t read_in_full(int fd, void *buf, size_t count)
43 nr = xread(fd, p, count);
59 ssize_t write_in_full(int fd, const void *buf, size_t count)
67 nr = xwrite(fd, p, count);
82 /* Same as pread(2) except that this function never returns EAGAIN or EINTR. */
83 ssize_t xpread(int fd, void *buf, size_t count, off_t offset)
88 nr = pread(fd, buf, count, offset);
89 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
95 /* Same as pwrite(2) except that this function never returns EAGAIN or EINTR. */
96 ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset)
101 nr = pwrite(fd, buf, count, offset);
102 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
108 ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset)
116 nr = xpread(fd, p, count, offset);
133 ssize_t pwrite_in_full(int fd, const void *buf, size_t count, off_t offset)
141 nr = xpwrite(fd, p, count, offset);
157 /* Same as readv(2) except that this function never returns EAGAIN or EINTR. */
158 ssize_t xreadv(int fd, const struct iovec *iov, int iovcnt)
163 nr = readv(fd, iov, iovcnt);
164 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
170 /* Same as writev(2) except that this function never returns EAGAIN or EINTR. */
171 ssize_t xwritev(int fd, const struct iovec *iov, int iovcnt)
176 nr = writev(fd, iov, iovcnt);
177 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
183 static inline ssize_t get_iov_size(const struct iovec *iov, int iovcnt)
187 size += (iov++)->iov_len;
192 static inline void shift_iovec(const struct iovec **iov, int *iovcnt,
193 size_t nr, ssize_t *total, size_t *count, off_t *offset)
195 while (nr >= (*iov)->iov_len) {
196 nr -= (*iov)->iov_len;
197 *total += (*iov)->iov_len;
198 *count -= (*iov)->iov_len;
200 *offset += (*iov)->iov_len;
206 ssize_t readv_in_full(int fd, const struct iovec *iov, int iovcnt)
209 size_t count = get_iov_size(iov, iovcnt);
214 nr = xreadv(fd, iov, iovcnt);
222 shift_iovec(&iov, &iovcnt, nr, &total, &count, NULL);
228 ssize_t writev_in_full(int fd, const struct iovec *iov, int iovcnt)
231 size_t count = get_iov_size(iov, iovcnt);
236 nr = xwritev(fd, iov, iovcnt);
244 shift_iovec(&iov, &iovcnt, nr, &total, &count, NULL);
250 /* Same as preadv(2) except that this function never returns EAGAIN or EINTR. */
251 ssize_t xpreadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
256 nr = preadv(fd, iov, iovcnt, offset);
257 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
263 /* Same as pwritev(2) except that this function never returns EAGAIN or EINTR. */
264 ssize_t xpwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
269 nr = pwritev(fd, iov, iovcnt, offset);
270 if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
276 ssize_t preadv_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset)
279 size_t count = get_iov_size(iov, iovcnt);
284 nr = xpreadv(fd, iov, iovcnt, offset);
292 shift_iovec(&iov, &iovcnt, nr, &total, &count, &offset);
298 ssize_t pwritev_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset)
301 size_t count = get_iov_size(iov, iovcnt);
306 nr = xpwritev(fd, iov, iovcnt, offset);
314 shift_iovec(&iov, &iovcnt, nr, &total, &count, &offset);
320 #ifdef CONFIG_HAS_AIO
321 int aio_pwritev(io_context_t ctx, struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt,
322 off_t offset, int ev, void *param)
324 struct iocb *ios[1] = { iocb };
327 io_prep_pwritev(iocb, fd, iov, iovcnt, offset);
328 io_set_eventfd(iocb, ev);
332 ret = io_submit(ctx, 1, ios);
338 int aio_preadv(io_context_t ctx, struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt,
339 off_t offset, int ev, void *param)
341 struct iocb *ios[1] = { iocb };
344 io_prep_preadv(iocb, fd, iov, iovcnt, offset);
345 io_set_eventfd(iocb, ev);
349 ret = io_submit(ctx, 1, ios);