From f42e42246fe7aba57cabc89ac5a439d03bde06b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 7 Apr 2021 19:09:31 +0200 Subject: [PATCH] terminal: drain PTY when client terminates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is done by: * Not limiting the number of times we try to read from the PTY when we’ve have POLLHUP * Not requiring the entire the previous read to have filled our buffer. * Not erroring out on EIO. --- CHANGELOG.md | 1 + terminal.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f0ed40f..46af71bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ * OSC-4/104 out-of-bounds accesses to the color table. This was the reason pywal turned foot windows transparent (https://codeberg.org/dnkl/foot/issues/434). +* PTY not being drained when the client application terminates. ### Security diff --git a/terminal.c b/terminal.c index b55a63a9..c6b4705c 100644 --- a/terminal.c +++ b/terminal.c @@ -230,15 +230,20 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data) uint8_t buf[24 * 1024]; ssize_t count = sizeof(buf); - const size_t max_iterations = 10; + const size_t max_iterations = !hup ? 10 : (size_t)-1ll; - for (size_t i = 0; i < max_iterations && pollin && count == sizeof(buf); i++) { + for (size_t i = 0; i < max_iterations && pollin; i++) { xassert(pollin); count = read(term->ptmx, buf, sizeof(buf)); if (count < 0) { - if (errno == EAGAIN) - return true; + if (errno == EAGAIN || errno == EIO) { + /* + * EAGAIN: no more to read - FDM will trigger us again + * EIO: assume PTY was closed - we already have, or will get, a EPOLLHUP + */ + break; + } LOG_ERRNO("failed to read from pseudo terminal"); return false;