rschmitt / heatseeker

A high-performance Selecta clone, written in Rust.
MIT License
214 stars 10 forks source link

Running heatseaker permanently changes TTY settings #29

Closed garybernhardt closed 5 years ago

garybernhardt commented 5 years ago

Reproduction steps:

Expected:

TTY state is unchanged after hs terminates, so git behaves in the same way.

Actual:

TTY state is permanently changed. But it only seems to affect other programs that mess with the TTY. It doesn't break shells or cat or vim. But it does break git and https://github.com/devlocker/tychus.

Details:

The TTY change is observable via stty:

$ stty
speed 38400 baud;
lflags: echoe echok echoke echoctl pendin
oflags: -oxtabs
cflags: cs8 -parenb

$ echo 'a' | hs
a

$ stty
speed 38400 baud;
lflags: echoke echoctl pendin
iflags: -icrnl ignbrk
oflags: -oxtabs
cflags: cs8 -parenb

Local configuration:

$ echo $SHELL
/usr/local/bin/zsh
$ zsh --version
zsh 5.2 (x86_64-apple-darwin15.4.0)
$ uname -a
Darwin failbowl.local 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64
$ hs --version
heatseeker 1.5.2 multi-threaded (cb2de6c) (built 2018-07-28 05:51:19 -0000 for x86_64-apple-darwin)
rschmitt commented 5 years ago

Can reproduce. How strange! The TTY change is also observable via stty -g, the before/after being:

iflag=2b02:lflag=200005cb iflag=2a03:lflag=200005c9

I suppose I'm either capturing the terminal state too late in hs's initialization or I'm making a false assumption about the behavior of stty $(stty -g).

rschmitt commented 5 years ago

Actually, I bet this has something to do with opening up /dev/tty. Note how I can't reproduce the problem interactively:

[0] ~/src/heatseeker # stty
speed 38400 baud;
lflags: echoe echoke echoctl pendin
oflags: -oxtabs
cflags: cs8 -parenb
[0] ~/src/heatseeker # ORIGINAL=$(stty -g)
[0] ~/src/heatseeker # stty raw -echo cbreak opost onlcr
[0] ~/src/heatseeker # stty
speed 38400 baud;
lflags: echoke echoctl pendin
iflags: -icrnl ignbrk
oflags: -oxtabs
cflags: cs8 -parenb
[0] ~/src/heatseeker # stty $ORIGINAL
[0] ~/src/heatseeker # stty
speed 38400 baud;
lflags: echoe echoke echoctl pendin
oflags: -oxtabs
cflags: cs8 -parenb

I bet git add -p is also opening /dev/tty and inheriting the dirty settings from hs.

garybernhardt commented 5 years ago

Interesting. Selecta also does stty $(stty -g), so that does seem to work as intended. Selecta opens the TTY with Ruby's IO.console. The comment on that (C) method seems to indicate that it's opening /dev/tty, but it may be doing other stuff, or there may have been other initialization done earlier in the IO system. I haven't dug through it in any more detail than that, but here it is: https://github.com/ruby/ruby/blob/1de78c5fd89e7da938b6f92200e851e119ea74b7/ext/io/console/console.c#L766

rschmitt commented 5 years ago

@garybernhardt This bug is as stupid as they come: I was capturing stty -g after setting raw mode on the terminal.

garybernhardt commented 5 years ago

Ha, that would do it. Glad you found it!