We use writev because sendmsg can only be used on socket fds. Signed-off-by: Orit Wasserman <owass...@redhat.com> --- include/qemu/iov.h | 12 ++++++++++++ util/iov.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+)
diff --git a/include/qemu/iov.h b/include/qemu/iov.h index 68d25f2..e26b7ba 100644 --- a/include/qemu/iov.h +++ b/include/qemu/iov.h @@ -82,6 +82,18 @@ ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, #define iov_send(sockfd, iov, iov_cnt, offset, bytes) \ iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, true) +/* + * writes iovcnt buffers of data described by iov to the file associated with + * the file descriptor fd. + * + * @fd - file descriptor + * @iov - iov to write + * @invcnt - number of buffers to write + * + * @return - number of bytes return or -1 on error + */ +ssize_t iov_writev(int fd, struct iovec *iov, unsigned iov_cnt); + /** * Produce a text hexdump of iovec `iov' with `iov_cnt' number of elements * in file `fp', prefixing each line with `prefix' and processing not more diff --git a/util/iov.c b/util/iov.c index 9dae318..bcd6e97 100644 --- a/util/iov.c +++ b/util/iov.c @@ -197,6 +197,42 @@ ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, return ret; } +ssize_t iov_writev(int fd, struct iovec *iov, unsigned iov_cnt) +{ +#if defined CONFIG_IOVEC && defined CONFIG_POSIX + ssize_t ret; + + do { + ret = writev(fd, iov, iov_cnt); + } while (ret < 0 && errno == EINTR); + + return ret; +#else + /* else send piece-by-piece */ + /*XXX Note: windows has WSASend() and WSARecv() */ + unsigned i = 0; + ssize_t ret = 0; + while (i < iov_cnt) { + ssize_t r = send(fd, iov[i].iov_base, iov[i].iov_len, 0); + if (r > 0) { + ret += r; + } else if (!r) { + break; + } else if (errno == EINTR) { + continue; + } else { + /* else it is some "other" error, + * only return if there was no data processed. */ + if (ret == 0) { + ret = -1; + } + break; + } + i++; + } + return ret; +#endif +} void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt, FILE *fp, const char *prefix, size_t limit) -- 1.7.11.7