From 8a4719e117445eadab24bb1a0b1811445a5f79c2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 23 Feb 2026 07:15:38 +0800 Subject: [PATCH] fix(process): use poll() to drain PTY master on Linux (#38005) On Linux, libuv's polling (which uses epoll) doesn't flush PTY master's pending work on kernel workqueue, so use an explicit poll() before that. --- src/nvim/event/proc.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/nvim/event/proc.c b/src/nvim/event/proc.c index eb8f2690a2..2413ab68d4 100644 --- a/src/nvim/event/proc.c +++ b/src/nvim/event/proc.c @@ -3,6 +3,9 @@ #include #include #include +#ifdef __linux__ +# include +#endif #include "klib/kvec.h" #include "nvim/channel.h" @@ -391,9 +394,17 @@ static void flush_stream(Proc *proc, RStream *stream) // Read remaining data. while (!stream->s.closed && stream->num_bytes < max_bytes) { - // Remember number of bytes before polling + // Remember number of bytes before polling. size_t num_bytes = stream->num_bytes; +#ifdef __linux__ + // On Linux, libuv's polling (which uses epoll) doesn't flush PTY master's pending + // work on kernel workqueue, so use an explcit poll() before that. #37982 + if (proc->type == kProcTypePty && !stream->did_eof) { + struct pollfd pollfd = { .fd = ((PtyProc *)proc)->tty_fd, .events = POLLIN }; + poll(&pollfd, 1, 0); + } +#endif // Poll for data and process the generated events. loop_poll_events(proc->loop, 0); if (stream->s.events) {