diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-09-05 14:14:32 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-09-05 14:14:33 +0100 |
commit | d3e3447d3df14001b364bcc9f6b296919a9f386e (patch) | |
tree | 7d948f61daf9b3138bb38008249391192c21b812 /io/channel.c | |
parent | 53e2c48d3f0db6a1598f49baf0b56dd4975e53a7 (diff) | |
parent | 689ed13e73bdb5a5ca3366524475e3065fae854a (diff) |
Merge remote-tracking branch 'remotes/berrange/tags/pull-qio-20170905-2' into staging
Merge QEMU I/O 2017/09/05 v2
# gpg: Signature made Tue 05 Sep 2017 13:22:36 BST
# gpg: using RSA key 0xBE86EBB415104FDF
# gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>"
# gpg: aka "Daniel P. Berrange <berrange@redhat.com>"
# Primary key fingerprint: DAF3 A6FD B26B 6291 2D0E 8E3F BE86 EBB4 1510 4FDF
* remotes/berrange/tags/pull-qio-20170905-2:
io: fix check for handshake completion in TLS test
io: add new qio_channel_{readv, writev, read, write}_all functions
io: fix typo in docs comment for qio_channel_read
util: remove the obsolete non-blocking connect
io: fix temp directory used by test-io-channel-tls test
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'io/channel.c')
-rw-r--r-- | io/channel.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/io/channel.c b/io/channel.c index 1cfb8b33a2..5e8c2f0a91 100644 --- a/io/channel.c +++ b/io/channel.c @@ -22,6 +22,7 @@ #include "io/channel.h" #include "qapi/error.h" #include "qemu/main-loop.h" +#include "qemu/iov.h" bool qio_channel_has_feature(QIOChannel *ioc, QIOChannelFeature feature) @@ -85,6 +86,79 @@ 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 ret = -1; + struct iovec *local_iov = g_new(struct iovec, niov); + struct iovec *local_iov_head = local_iov; + unsigned int nlocal_iov = niov; + + nlocal_iov = iov_copy(local_iov, nlocal_iov, + iov, niov, + 0, iov_size(iov, niov)); + + while (nlocal_iov > 0) { + ssize_t len; + len = qio_channel_readv(ioc, local_iov, nlocal_iov, errp); + if (len == QIO_CHANNEL_ERR_BLOCK) { + qio_channel_wait(ioc, G_IO_IN); + continue; + } else if (len < 0) { + goto cleanup; + } else if (len == 0) { + error_setg(errp, + "Unexpected end-of-file before all bytes were read"); + goto cleanup; + } + + iov_discard_front(&local_iov, &nlocal_iov, len); + } + + ret = 0; + + cleanup: + g_free(local_iov_head); + return ret; +} + +int qio_channel_writev_all(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; + + nlocal_iov = iov_copy(local_iov, nlocal_iov, + iov, niov, + 0, iov_size(iov, niov)); + + while (nlocal_iov > 0) { + ssize_t len; + len = qio_channel_writev(ioc, local_iov, nlocal_iov, errp); + if (len == QIO_CHANNEL_ERR_BLOCK) { + qio_channel_wait(ioc, G_IO_OUT); + continue; + } + if (len < 0) { + goto cleanup; + } + + iov_discard_front(&local_iov, &nlocal_iov, len); + } + + ret = 0; + cleanup: + g_free(local_iov_head); + return ret; +} + ssize_t qio_channel_readv(QIOChannel *ioc, const struct iovec *iov, size_t niov, @@ -123,6 +197,26 @@ ssize_t qio_channel_write(QIOChannel *ioc, } +int qio_channel_read_all(QIOChannel *ioc, + char *buf, + size_t buflen, + Error **errp) +{ + struct iovec iov = { .iov_base = buf, .iov_len = buflen }; + return qio_channel_readv_all(ioc, &iov, 1, errp); +} + + +int qio_channel_write_all(QIOChannel *ioc, + const char *buf, + size_t buflen, + Error **errp) +{ + struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen }; + return qio_channel_writev_all(ioc, &iov, 1, errp); +} + + int qio_channel_set_blocking(QIOChannel *ioc, bool enabled, Error **errp) |