Avoid needing to initialize tty state in bootstrap scripts

This commit is contained in:
Kovid Goyal
2022-03-13 12:03:28 +05:30
parent 74f0057ec8
commit e1504c4775
5 changed files with 96 additions and 122 deletions

View File

@@ -16,7 +16,7 @@ import tempfile
import termios
tty_fd = -1
original_termios_state = None
echo_on = int('ECHO_ON')
data_dir = shell_integration_dir = ''
request_data = int('REQUEST_DATA')
leading_data = b''
@@ -25,11 +25,12 @@ login_shell = pwd.getpwuid(os.geteuid()).pw_shell or 'sh'
def cleanup():
global tty_fd, original_termios_state
global tty_fd
if tty_fd > -1:
if original_termios_state is not None:
termios.tcsetattr(tty_fd, termios.TCSANOW, original_termios_state)
original_termios_state = None
if echo_on:
s = termios.tcgetattr(tty_fd)
s[3] |= termios.ECHO
termios.tcsetattr(tty_fd, termios.TCSANOW, s)
os.close(tty_fd)
tty_fd = -1
@@ -150,7 +151,6 @@ def get_data():
data = []
with open(tty_fd, 'rb', closefd=False) as f:
data = b''.join(iter_base64_data(f))
cleanup()
if leading_data:
# clear current line as it might have things echoed on it from leading_data
# because we only turn off echo in this script whereas the leading bytes could
@@ -214,26 +214,11 @@ def exec_with_shell_integration():
def main():
global tty_fd, original_termios_state, login_shell
global tty_fd, login_shell
tty_fd = os.open(os.ctermid(), os.O_RDWR | os.O_CLOEXEC)
try:
tty_fd = os.open(os.ctermid(), os.O_RDWR | os.O_CLOEXEC)
except OSError:
pass
else:
if request_data:
try:
original_termios_state = termios.tcgetattr(tty_fd)
except OSError:
pass
else:
new_state = termios.tcgetattr(tty_fd)
new_state[3] &= ~termios.ECHO
termios.tcsetattr(tty_fd, termios.TCSANOW, new_state)
try:
if original_termios_state is not None:
send_data_request()
if tty_fd > -1:
get_data()
send_data_request()
get_data()
finally:
cleanup()
cwd = os.environ.pop('KITTY_LOGIN_CWD', '')

View File

@@ -2,14 +2,14 @@
# Copyright (C) 2022 Kovid Goyal <kovid at kovidgoyal.net>
# Distributed under terms of the GPLv3 license.
saved_tty_settings=""
tdir=""
shell_integration_dir=""
echo_on="ECHO_ON"
cleanup_on_bootstrap_exit() {
[ -n "$saved_tty_settings" ] && command stty "$saved_tty_settings" 2> /dev/null < /dev/tty
[ "$echo_on" = "1" ] && command stty "echo" 2> /dev/null < /dev/tty
echo_on="0"
[ -n "$tdir" ] && command rm -rf "$tdir"
saved_tty_settings=""
tdir=""
}
@@ -58,18 +58,6 @@ else
die "base64 executable not present on remote host, ssh kitten cannot function."
fi
init_tty() {
saved_tty_settings=$(command stty -g 2> /dev/null < /dev/tty)
tty_ok="n"
[ -n "$saved_tty_settings" ] && tty_ok="y"
if [ "$tty_ok" = "y" ]; then
command stty -echo 2> /dev/null < /dev/tty || die "stty failed to set raw mode"
return 0
fi
return 1
}
dcs_to_kitty() { printf "\033P@kitty-$1|%s\033\134" "$(printf "%s" "$2" | base64_encode)" > /dev/tty; }
debug() { dcs_to_kitty "print" "debug: $1"; }
echo_via_kitty() { dcs_to_kitty "echo" "$1"; }
@@ -84,11 +72,8 @@ leading_data=""
login_cwd=""
request_data="REQUEST_DATA"
[ "$request_data" = "1" ] && init_tty
trap "cleanup_on_bootstrap_exit" EXIT
if [ "$tty_ok" = "y" -a "$request_data" = "1" ]; then
dcs_to_kitty "ssh" "id="REQUEST_ID":pwfile="PASSWORD_FILENAME":pw="DATA_PASSWORD""
fi
dcs_to_kitty "ssh" "id="REQUEST_ID":pwfile="PASSWORD_FILENAME":pw="DATA_PASSWORD""
record_separator=$(printf "\036")
mv_files_and_dirs() {
@@ -177,18 +162,16 @@ get_data() {
untar_and_read_env
}
if [ "$tty_ok" = "y" ]; then
# ask for the SSH data
get_data
cleanup_on_bootstrap_exit
if [ -n "$leading_data" ]; then
# clear current line as it might have things echoed on it from leading_data
# because we only turn off echo in this script whereas the leading bytes could
# have been sent before the script had a chance to run
printf "\r\033[K" > /dev/tty
fi
[ -f "$HOME/.terminfo/kitty.terminfo" ] || die "Incomplete extraction of ssh data"
# ask for the SSH data
get_data
cleanup_on_bootstrap_exit
if [ -n "$leading_data" ]; then
# clear current line as it might have things echoed on it from leading_data
# because we only turn off echo in this script whereas the leading bytes could
# have been sent before the script had a chance to run
printf "\r\033[K" > /dev/tty
fi
[ -f "$HOME/.terminfo/kitty.terminfo" ] || die "Incomplete extraction of ssh data"
login_shell_is_ok() {
if [ -n "$login_shell" -a -x "$login_shell" ]; then return 0; fi
@@ -282,14 +265,6 @@ shell_name=$(command basename $login_shell)
# If a command was passed to SSH execute it here
EXEC_CMD
if [ "$tty_ok" = "n" ]; then
if [ -z "$(command -v stty)" ]; then
printf "%s\n" "stty missing ssh kitten cannot function" > /dev/stderr
else
printf "%s\n" "stty failed ssh kitten cannot function" > /dev/stderr
fi
fi
exec_zsh_with_integration() {
zdotdir="$ZDOTDIR"
if [ -z "$zdotdir" ]; then