diff options
Diffstat (limited to 'io')
-rw-r--r-- | io/channel.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/io/channel.c b/io/channel.c index 9e62794cab..ec4b86de7c 100644 --- a/io/channel.c +++ b/io/channel.c @@ -86,16 +86,16 @@ ssize_t qio_channel_writev_full(QIOChannel *ioc, } - -int qio_channel_readv_all(QIOChannel *ioc, - const struct iovec *iov, - size_t niov, - Error **errp) +int qio_channel_readv_all_eof(QIOChannel *ioc, + const struct iovec *iov, + size_t niov, + Error **errp) { int ret = -1; struct iovec *local_iov = g_new(struct iovec, niov); struct iovec *local_iov_head = local_iov; unsigned int nlocal_iov = niov; + bool partial = false; nlocal_iov = iov_copy(local_iov, nlocal_iov, iov, niov, @@ -114,21 +114,43 @@ int qio_channel_readv_all(QIOChannel *ioc, } else if (len < 0) { goto cleanup; } else if (len == 0) { - error_setg(errp, - "Unexpected end-of-file before all bytes were read"); + if (partial) { + error_setg(errp, + "Unexpected end-of-file before all bytes were read"); + } else { + ret = 0; + } goto cleanup; } + partial = true; iov_discard_front(&local_iov, &nlocal_iov, len); } - ret = 0; + ret = 1; cleanup: g_free(local_iov_head); return ret; } +int qio_channel_readv_all(QIOChannel *ioc, + const struct iovec *iov, + size_t niov, + Error **errp) +{ + int ret = qio_channel_readv_all_eof(ioc, iov, niov, errp); + + if (ret == 0) { + ret = -1; + error_setg(errp, + "Unexpected end-of-file before all bytes were read"); + } else if (ret == 1) { + ret = 0; + } + return ret; +} + int qio_channel_writev_all(QIOChannel *ioc, const struct iovec *iov, size_t niov, @@ -205,6 +227,16 @@ ssize_t qio_channel_write(QIOChannel *ioc, } +int qio_channel_read_all_eof(QIOChannel *ioc, + char *buf, + size_t buflen, + Error **errp) +{ + struct iovec iov = { .iov_base = buf, .iov_len = buflen }; + return qio_channel_readv_all_eof(ioc, &iov, 1, errp); +} + + int qio_channel_read_all(QIOChannel *ioc, char *buf, size_t buflen, |