diff options
-rw-r--r-- | include/char/char.h | 15 | ||||
-rw-r--r-- | qemu-char.c | 27 |
2 files changed, 42 insertions, 0 deletions
diff --git a/include/char/char.h b/include/char/char.h index 0326b2a47b..5c3a7a5756 100644 --- a/include/char/char.h +++ b/include/char/char.h @@ -170,6 +170,21 @@ int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len); /** + * @qemu_chr_fe_write_all: + * + * Write data to a character backend from the front end. This function will + * send data from the front end to the back end. Unlike @qemu_chr_fe_write, + * this function will block if the back end cannot consume all of the data + * attempted to be written. + * + * @buf the data + * @len the number of bytes to send + * + * Returns: the number of bytes consumed + */ +int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len); + +/** * @qemu_chr_fe_ioctl: * * Issue a device specific ioctl to a backend. diff --git a/qemu-char.c b/qemu-char.c index 4e011df3ec..936150fa73 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -140,6 +140,33 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len) return s->chr_write(s, buf, len); } +int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len) +{ + int offset = 0; + int res; + + while (offset < len) { + do { + res = s->chr_write(s, buf + offset, len - offset); + if (res == -1 && errno == EAGAIN) { + g_usleep(100); + } + } while (res == -1 && errno == EAGAIN); + + if (res == 0) { + break; + } + + if (res < 0) { + return res; + } + + offset += res; + } + + return offset; +} + int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg) { if (!s->chr_ioctl) |