#include "kvm/read-write.h"

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

/* Same as read(2) except that this function never returns EAGAIN or EINTR. */
ssize_t xread(int fd, void *buf, size_t count)
{
	ssize_t nr;

restart:
	nr = read(fd, buf, count);
	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
		goto restart;

	return nr;
}

/* Same as write(2) except that this function never returns EAGAIN or EINTR. */
ssize_t xwrite(int fd, const void *buf, size_t count)
{
	ssize_t nr;

restart:
	nr = write(fd, buf, count);
	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
		goto restart;

	return nr;
}

/*
 * Read in the whole file while not exceeding max_size bytes of the buffer.
 * Returns -1 (with errno set) in case of an error (ENOMEM if buffer was
 * too small) or the filesize if the whole file could be read.
 */
ssize_t read_file(int fd, char *buf, size_t max_size)
{
	ssize_t ret;
	char dummy;

	errno = 0;
	ret = read_in_full(fd, buf, max_size);

	/* Probe whether we reached EOF. */
	if (xread(fd, &dummy, 1) == 0)
		return ret;

	errno = ENOMEM;
	return -1;
}

ssize_t read_in_full(int fd, void *buf, size_t count)
{
	ssize_t total = 0;
	char *p = buf;

	while (count > 0) {
		ssize_t nr;

		nr = xread(fd, p, count);
		if (nr <= 0) {
			if (total > 0)
				return total;

			return -1;
		}

		count -= nr;
		total += nr;
		p += nr;
	}

	return total;
}

ssize_t write_in_full(int fd, const void *buf, size_t count)
{
	const char *p = buf;
	ssize_t total = 0;

	while (count > 0) {
		ssize_t nr;

		nr = xwrite(fd, p, count);
		if (nr < 0)
			return -1;
		if (nr == 0) {
			errno = ENOSPC;
			return -1;
		}
		count -= nr;
		total += nr;
		p += nr;
	}

	return total;
}

/* Same as pread(2) except that this function never returns EAGAIN or EINTR. */
ssize_t xpread(int fd, void *buf, size_t count, off_t offset)
{
	ssize_t nr;

restart:
	nr = pread(fd, buf, count, offset);
	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
		goto restart;

	return nr;
}

/* Same as pwrite(2) except that this function never returns EAGAIN or EINTR. */
ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset)
{
	ssize_t nr;

restart:
	nr = pwrite(fd, buf, count, offset);
	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
		goto restart;

	return nr;
}

ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset)
{
	ssize_t total = 0;
	char *p = buf;

	while (count > 0) {
		ssize_t nr;

		nr = xpread(fd, p, count, offset);
		if (nr <= 0) {
			if (total > 0)
				return total;

			return -1;
		}

		count -= nr;
		total += nr;
		p += nr;
		offset += nr;
	}

	return total;
}

ssize_t pwrite_in_full(int fd, const void *buf, size_t count, off_t offset)
{
	const char *p = buf;
	ssize_t total = 0;

	while (count > 0) {
		ssize_t nr;

		nr = xpwrite(fd, p, count, offset);
		if (nr < 0)
			return -1;
		if (nr == 0) {
			errno = ENOSPC;
			return -1;
		}
		count -= nr;
		total += nr;
		p += nr;
		offset += nr;
	}

	return total;
}

/* Same as readv(2) except that this function never returns EAGAIN or EINTR. */
ssize_t xreadv(int fd, const struct iovec *iov, int iovcnt)
{
	ssize_t nr;

restart:
	nr = readv(fd, iov, iovcnt);
	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
		goto restart;

	return nr;
}

/* Same as writev(2) except that this function never returns EAGAIN or EINTR. */
ssize_t xwritev(int fd, const struct iovec *iov, int iovcnt)
{
	ssize_t nr;

restart:
	nr = writev(fd, iov, iovcnt);
	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
		goto restart;

	return nr;
}

static inline ssize_t get_iov_size(const struct iovec *iov, int iovcnt)
{
	size_t size = 0;
	while (iovcnt--)
		size += (iov++)->iov_len;

	return size;
}

static inline void shift_iovec(const struct iovec **iov, int *iovcnt,
				size_t nr, ssize_t *total, size_t *count, off_t *offset)
{
	while (nr >= (*iov)->iov_len) {
		nr -= (*iov)->iov_len;
		*total += (*iov)->iov_len;
		*count -= (*iov)->iov_len;
		if (offset)
			*offset += (*iov)->iov_len;
		(*iovcnt)--;
		(*iov)++;
	}
}

ssize_t readv_in_full(int fd, const struct iovec *iov, int iovcnt)
{
	ssize_t total = 0;
	size_t count = get_iov_size(iov, iovcnt);

	while (count > 0) {
		ssize_t nr;

		nr = xreadv(fd, iov, iovcnt);
		if (nr <= 0) {
			if (total > 0)
				return total;

			return -1;
		}

		shift_iovec(&iov, &iovcnt, nr, &total, &count, NULL);
	}

	return total;
}

ssize_t writev_in_full(int fd, const struct iovec *iov, int iovcnt)
{
	ssize_t total = 0;
	size_t count = get_iov_size(iov, iovcnt);

	while (count > 0) {
		ssize_t nr;

		nr = xwritev(fd, iov, iovcnt);
		if (nr < 0)
			return -1;
		if (nr == 0) {
			errno = ENOSPC;
			return -1;
		}

		shift_iovec(&iov, &iovcnt, nr, &total, &count, NULL);
	}

	return total;
}

/* Same as preadv(2) except that this function never returns EAGAIN or EINTR. */
ssize_t xpreadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
{
	ssize_t nr;

restart:
	nr = preadv(fd, iov, iovcnt, offset);
	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
		goto restart;

	return nr;
}

/* Same as pwritev(2) except that this function never returns EAGAIN or EINTR. */
ssize_t xpwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
{
	ssize_t nr;

restart:
	nr = pwritev(fd, iov, iovcnt, offset);
	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
		goto restart;

	return nr;
}

ssize_t preadv_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset)
{
	ssize_t total = 0;
	size_t count = get_iov_size(iov, iovcnt);

	while (count > 0) {
		ssize_t nr;

		nr = xpreadv(fd, iov, iovcnt, offset);
		if (nr <= 0) {
			if (total > 0)
				return total;

			return -1;
		}

		shift_iovec(&iov, &iovcnt, nr, &total, &count, &offset);
	}

	return total;
}

ssize_t pwritev_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset)
{
	ssize_t total = 0;
	size_t count = get_iov_size(iov, iovcnt);

	while (count > 0) {
		ssize_t nr;

		nr = xpwritev(fd, iov, iovcnt, offset);
		if (nr < 0)
			return -1;
		if (nr == 0) {
			errno = ENOSPC;
			return -1;
		}

		shift_iovec(&iov, &iovcnt, nr, &total, &count, &offset);
	}

	return total;
}
