From c2a131714a6b9eccba7779bde64ce79a0377b541 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 6 Jun 2022 19:42:07 -0600 Subject: [PATCH] Reinstall the event handler if we get EAGAIN from read/write callback. The read and write events do not set SUDO_EV_PERSIST so we need to explicitly re-enable the event if there is still data to be read. Bug #963. --- src/exec_pty.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/exec_pty.c b/src/exec_pty.c index 326d8318a..d2fc1ce5c 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -676,8 +676,12 @@ read_callback(int fd, int what, void *v) /* Schedule SIGTTIN to be forwarded to the command. */ schedule_signal(iob->ec, SIGTTIN); } - if (errno == EAGAIN || errno == EINTR) + if (errno == EAGAIN || errno == EINTR) { + /* Re-enable reader. */ + if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1) + sudo_fatal("%s", U_("unable to add event to queue")); break; + } /* treat read error as fatal and close the fd */ sudo_debug_printf(SUDO_DEBUG_ERROR, "error reading fd %d: %s", fd, strerror(errno)); @@ -717,6 +721,8 @@ read_callback(int fd, int what, void *v) } break; } + + debug_return; } /* @@ -783,7 +789,9 @@ write_callback(int fd, int what, void *v) } FALLTHROUGH; case EAGAIN: - /* not an error */ + /* Not an error, re-enable writer. */ + if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1) + sudo_fatal("%s", U_("unable to add event to queue")); break; default: /* XXX - need a way to distinguish non-exec error. */ @@ -821,6 +829,8 @@ write_callback(int fd, int what, void *v) } } } + + debug_return; } static void