[-- Attachment #1: Type: text/plain, Size: 731 bytes --] When TTY disappears and there is at least one fd watcher, raw_getbyte() can enter an infinite loop where it keeps calling poll() over and over again. To reproduce, open a terminal, start zsh and type this: rm -f /tmp/fifo mkfifo /tmp/fifo exec 3<>/tmp/fifo do-nothing() {} zle -F 3 do-nothing Then make TTY disappear. For example, kill the parent with `kill -9 $PPID` and close the terminal window if it's still there. Observe that zsh is consuming 100% CPU. Note that do-nothing() never gets called. This patch makes the poll() loop in raw_getbyte() terminate when TTY is signalling POLLHUP. This makes the behavior consistent with the case where TTY disappears while no fd watchers are installed. Roman. [-- Attachment #2: patch.txt --] [-- Type: text/plain, Size: 394 bytes --] diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index d3b9aeab8..22c12cf1f 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -708,7 +708,7 @@ raw_getbyte(long do_keytmout, char *cptr, int full) */ if ( # ifdef HAVE_POLL - (fds[0].revents & POLLIN) + (fds[0].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL)) # else FD_ISSET(SHTTY, &foofd) # endif