mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
io: add new qio_channel_{readv, writev, read, write}_all functions
These functions wait until they are able to read / write the full requested data buffer(s). Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
50ea44f077
commit
d4622e5588
3 changed files with 193 additions and 93 deletions
94
io/channel.c
94
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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue