summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2017-12-08 15:14:26 -0500
committerJan Ekström <jeebjp@gmail.com>2017-12-09 21:37:44 +0200
commitf60bfd1ad5e61b41df5162770c8684cf993dfdad (patch)
tree45514fd061cb1b0ff697715ca7c8137cac46df77
parenta0fc195112d6455403e2fcee9c31119a1f3e6d9a (diff)
downloadmpv-f60bfd1ad5e61b41df5162770c8684cf993dfdad.tar.bz2
mpv-f60bfd1ad5e61b41df5162770c8684cf993dfdad.tar.xz
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
-rw-r--r--osdep/terminal-unix.c20
1 files 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);