summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/char/char.h4
-rw-r--r--monitor.c23
-rw-r--r--qemu-char.c4
3 files changed, 25 insertions, 6 deletions
diff --git a/include/char/char.h b/include/char/char.h
index d6a03513bf..0326b2a47b 100644
--- a/include/char/char.h
+++ b/include/char/char.h
@@ -153,8 +153,8 @@ void qemu_chr_fe_close(struct CharDriverState *chr);
void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
-guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
- GIOFunc func, void *user_data);
+int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
+ GIOFunc func, void *user_data);
/**
* @qemu_chr_fe_write:
diff --git a/monitor.c b/monitor.c
index 112e92064d..680d344211 100644
--- a/monitor.c
+++ b/monitor.c
@@ -261,11 +261,30 @@ int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
}
}
+static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond,
+ void *opaque)
+{
+ monitor_flush(opaque);
+ return FALSE;
+}
+
void monitor_flush(Monitor *mon)
{
+ int rc;
+
if (mon && mon->outbuf_index != 0 && !mon->mux_out) {
- qemu_chr_fe_write(mon->chr, mon->outbuf, mon->outbuf_index);
- mon->outbuf_index = 0;
+ rc = qemu_chr_fe_write(mon->chr, mon->outbuf, mon->outbuf_index);
+ if (rc == mon->outbuf_index) {
+ /* all flushed */
+ mon->outbuf_index = 0;
+ return;
+ }
+ if (rc > 0) {
+ /* partinal write */
+ memmove(mon->outbuf, mon->outbuf + rc, mon->outbuf_index - rc);
+ mon->outbuf_index -= rc;
+ }
+ qemu_chr_fe_add_watch(mon->chr, G_IO_OUT, monitor_unblocked, mon);
}
}
diff --git a/qemu-char.c b/qemu-char.c
index e6337971a5..4e011df3ec 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3397,8 +3397,8 @@ void qemu_chr_fe_close(struct CharDriverState *chr)
}
}
-guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
- GIOFunc func, void *user_data)
+int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
+ GIOFunc func, void *user_data)
{
GSource *src;
guint tag;