@samitouri / QOSamiQemu / commits / 54293f80a9

ui/console-vc: unify the write path

VT100 escape responses (DSR) used qemu_chr_be_write() to write directly to the chardev backend, bypassing the output FIFO, while keyboard input went through the FIFO and flush path. This inconsistency could lead to out-of-order delivery when both paths are active. Introduce qemu_text_console_write() that pushes data into the output FIFO and flushes it, and use it for both keyboard input and VT100 responses. Remove the now-unnecessary vc_respond_str() helper. Rename kbd_send_chars() to qemu_text_console_flush() to better reflect its purpose. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Marc-André Lureau committed Feb 19, 2026 at 15:07 UTC 54293f80a915a8108c2f3439f0ba07243b09559e
1 file changed +14 -15
ui/console-vc.c
+14 -15
@@ -296,7 +296,7 @@ static void vt100_scroll(QemuVT100 *vt, int ydelta)
296 vt100_refresh(vt);
297 }
298
299 -static void kbd_send_chars(QemuTextConsole *s)
299 +static void qemu_text_console_flush(QemuTextConsole *s)
300 {
301 uint32_t len, avail;
302
@@ -313,13 +313,21 @@ static void kbd_send_chars(QemuTextConsole *s)
313 }
314 }
315
316 +static void qemu_text_console_write(QemuTextConsole *s, const void *buf, size_t len)
317 +{
318 + uint32_t num_free;
319 +
320 + num_free = fifo8_num_free(&s->out_fifo);
321 + fifo8_push_all(&s->out_fifo, buf, MIN(num_free, len));
322 + qemu_text_console_flush(s);
323 +}
324 +
325 /* called when an ascii key is pressed */
326 void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)
327 {
328 QemuVT100 *vt = &s->vt;
329 uint8_t buf[16], *q;
330 int c;
322 - uint32_t num_free;
331
332 switch(keysym) {
333 case QEMU_KEY_CTRL_UP:
@@ -358,9 +366,7 @@ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)
366 if (vt->echo) {
367 qemu_chr_write(s->chr, buf, q - buf, true);
368 }
361 - num_free = fifo8_num_free(&s->out_fifo);
362 - fifo8_push_all(&s->out_fifo, buf, MIN(num_free, q - buf));
363 - kbd_send_chars(s);
369 + qemu_text_console_write(s, buf, q - buf);
370 break;
371 }
372 }
@@ -634,13 +640,6 @@ static void vc_put_one(VCChardev *vc, int ch)
640 vt->x++;
641 }
642
637 -static void vc_respond_str(VCChardev *vc, const char *buf)
638 -{
639 - QemuTextConsole *s = vc->console;
640 -
641 - qemu_chr_be_write(s->chr, (const uint8_t *)buf, strlen(buf));
642 -}
643 -
643 /* set cursor, checking bounds */
644 static void vc_set_cursor(VCChardev *vc, int x, int y)
645 {
@@ -967,13 +966,13 @@ static void vc_putchar(VCChardev *vc, int ch)
966 switch (vc->esc_params[0]) {
967 case 5:
968 /* report console status (always succeed)*/
970 - vc_respond_str(vc, "\033[0n");
969 + qemu_text_console_write(s, "\033[0n", 4);
970 break;
971 case 6:
972 /* report cursor position */
973 response = g_strdup_printf("\033[%d;%dR",
974 vt->y + 1, vt->x + 1);
976 - vc_respond_str(vc, response);
975 + qemu_text_console_write(s, response, strlen(response));
976 break;
977 }
978 break;
@@ -1133,7 +1132,7 @@ static void vc_chr_accept_input(Chardev *chr)
1132 {
1133 VCChardev *drv = VC_CHARDEV(chr);
1134
1136 - kbd_send_chars(drv->console);
1135 + qemu_text_console_flush(drv->console);
1136 }
1137
1138 static void vc_chr_set_echo(Chardev *chr, bool echo)