From f60bfd1ad5e61b41df5162770c8684cf993dfdad Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 8 Dec 2017 15:14:26 -0500 Subject: 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 --- osdep/terminal-unix.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/osdep/terminal-unix.c b/osdep/terminal-unix.c index 0eca44372e..1e909522b7 100644 --- a/osdep/terminal-unix.c +++ b/osdep/terminal-unix.c @@ -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); -- cgit v1.2.3