From 9d52c422e1856ee1de759254f6ca9046bae5e485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 5 Feb 2020 19:50:49 +0100 Subject: [PATCH] term: always read *all* we can from the client before updating state But place an upper limit on the number of iterations we read, to prevent starvation caused by a bad behaving client to constantly writes data. --- terminal.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/terminal.c b/terminal.c index 69f3c5d2..6152c739 100644 --- a/terminal.c +++ b/terminal.c @@ -147,19 +147,26 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data) return true; #endif - uint8_t buf[24 * 1024]; - ssize_t count = pollin ? read(term->ptmx, buf, sizeof(buf)) : 0; - - if (count < 0) { - LOG_ERRNO("failed to read from pseudo terminal"); - return false; - } - - vt_from_slave(term, buf, count); - /* Prevent blinking while typing */ term_cursor_blink_restart(term); + uint8_t buf[24 * 1024]; + ssize_t count = sizeof(buf); + + const size_t max_iterations = 1024; + + for (size_t i = 0; i < max_iterations && pollin && count == sizeof(buf); i++) { + assert(pollin); + count = read(term->ptmx, buf, sizeof(buf)); + + if (count < 0) { + LOG_ERRNO("failed to read from pseudo terminal"); + return false; + } + + vt_from_slave(term, buf, count); + } + /* * We likely need to re-render. But, we don't want to * do it immediately. Often, a single client operation