terminal-unix: fix race condition with tty reset

Calling do_deactivate_getch2 before joining the terminal thread could
lead to breakage if the terminal thread got another interation in before
it was signaled to stop.

This also addresses a minor error with the order in which things are
initialized - getch2_poll would previously call tcgetpgrp(tty_in) before
tty_in was initialized, which did not lead to broken behavior, but was
not correct either.

Fixes #5195
This commit is contained in:
Drew DeVault 2017-12-08 15:14:26 -05:00 committed by Jan Ekström
parent a0fc195112
commit f60bfd1ad5
1 changed files with 10 additions and 10 deletions

View File

@ -45,7 +45,7 @@
static volatile struct termios tio_orig;
static volatile int tio_orig_set;
static int tty_in, tty_out;
static int tty_in = -1, tty_out = -1;
struct key_entry {
const char *seq;
@ -417,12 +417,6 @@ void terminal_setup_getch(struct input_ctx *ictx)
if (mp_make_wakeup_pipe(death_pipe) < 0)
return;
tty_in = tty_out = open("/dev/tty", O_RDWR | O_CLOEXEC);
if (tty_in < 0) {
tty_in = STDIN_FILENO;
tty_out = STDOUT_FILENO;
}
// Disable reading from the terminal even if stdout is not a tty, to make
// mpv ... | less
// do the right thing.
@ -456,16 +450,16 @@ void terminal_uninit(void)
setsigaction(SIGTTIN, SIG_DFL, 0, false);
setsigaction(SIGTTOU, SIG_DFL, 0, false);
do_deactivate_getch2();
if (input_ctx) {
(void)write(death_pipe[1], &(char){0}, 1);
pthread_join(input_thread, NULL);
close_death_pipe();
close_tty();
input_ctx = NULL;
}
do_deactivate_getch2();
close_tty();
getch2_enabled = 0;
read_terminal = false;
}
@ -490,6 +484,12 @@ void terminal_init(void)
assert(!getch2_enabled);
getch2_enabled = 1;
tty_in = tty_out = open("/dev/tty", O_RDWR | O_CLOEXEC);
if (tty_in < 0) {
tty_in = STDIN_FILENO;
tty_out = STDOUT_FILENO;
}
// handlers to fix terminal settings
setsigaction(SIGCONT, continue_sighandler, 0, true);
setsigaction(SIGTSTP, stop_sighandler, SA_RESETHAND, false);