terminal-unix: fix not listening on input after being foregrounded

fixes regression caused by 2e7fcc5a2 where it wouldn't receive terminal
input if the process was foregrounded later on like this:

    $ mpv something.mp4 &
    $ fg

ref: https://github.com/mpv-player/mpv/issues/11795
This commit is contained in:
NRK
2023-07-20 23:31:30 +06:00
committed by sfan5
parent 4198e6f35f
commit 2dc8e70093
+13 -2
View File
@@ -415,12 +415,23 @@ static void *terminal_thread(void *ptr)
{ .events = POLLIN, .fd = death_pipe[0] },
{ .events = POLLIN, .fd = tty_in }
};
int r = polldev(fds, stdin_ok ? 2 : 1, buf.len ? ESC_TIMEOUT : INPUT_TIMEOUT);
/*
* if the process isn't in foreground process group, then on macos
* polldev() doesn't rest and gets into 100% cpu usage (see issue #11795)
* with read() returning EIO. but we shouldn't quit on EIO either since
* the process might be foregrounded later.
*
* so just avoid poll-ing tty_in when we know the process is not in the
* foreground. there's a small race window, but the timeout will take
* care of it so it's fine.
*/
bool is_fg = tcgetpgrp(tty_in) == getpgrp();
int r = polldev(fds, stdin_ok && is_fg ? 2 : 1, buf.len ? ESC_TIMEOUT : INPUT_TIMEOUT);
if (fds[0].revents)
break;
if (fds[1].revents) {
int retval = read(tty_in, &buf.b[buf.len], BUF_LEN - buf.len);
if (!retval || (retval == -1 && errno != EINTR && errno != EAGAIN))
if (!retval || (retval == -1 && errno != EINTR && errno != EAGAIN && errno != EIO))
break; // EOF/closed
if (retval > 0) {
buf.len += retval;