aboutsummaryrefslogtreecommitdiff
path: root/vl.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-09-03 15:28:58 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-09-03 15:28:58 +0000
commitaa0bc6b68c98d4b8122a846c962a1bac1c329ca4 (patch)
treefe999532ac47ff28e99c6be8c245bb93c717ff77 /vl.c
parent1c213d197626942201052f19be2b5f83370a6b36 (diff)
avoid losing chars in serial console
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1564 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'vl.c')
-rw-r--r--vl.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/vl.c b/vl.c
index 354968d619..9819916a11 100644
--- a/vl.c
+++ b/vl.c
@@ -1138,7 +1138,11 @@ CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
+#define TERM_FIFO_MAX_SIZE 1
+
static int term_got_escape, client_index;
+static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
+int term_fifo_size;
void term_print_help(void)
{
@@ -1207,19 +1211,37 @@ static void stdio_received_byte(int ch)
chr = stdio_clients[client_index];
s = chr->opaque;
- buf[0] = ch;
- /* XXX: should queue the char if the device is not
- ready */
- if (s->fd_can_read(s->fd_opaque) > 0)
+ if (s->fd_can_read(s->fd_opaque) > 0) {
+ buf[0] = ch;
s->fd_read(s->fd_opaque, buf, 1);
+ } else if (term_fifo_size == 0) {
+ term_fifo[term_fifo_size++] = ch;
+ }
}
}
}
static int stdio_can_read(void *opaque)
{
- /* XXX: not strictly correct */
- return 1;
+ CharDriverState *chr;
+ FDCharDriver *s;
+
+ if (client_index < stdio_nb_clients) {
+ chr = stdio_clients[client_index];
+ s = chr->opaque;
+ /* try to flush the queue if needed */
+ if (term_fifo_size != 0 && s->fd_can_read(s->fd_opaque) > 0) {
+ s->fd_read(s->fd_opaque, term_fifo, 1);
+ term_fifo_size = 0;
+ }
+ /* see if we can absorb more chars */
+ if (term_fifo_size == 0)
+ return 1;
+ else
+ return 0;
+ } else {
+ return 1;
+ }
}
static void stdio_read(void *opaque, const uint8_t *buf, int size)