From fda9415873eccf15f677a98ae96a7681e3fa1482 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 24 Feb 2022 19:41:21 +0530 Subject: [PATCH] Use a record separator to delimit the start of data Needed because the user could press keys and send data to the tty before kitty can send the ssh data --- kittens/ssh/main.py | 2 +- shell-integration/ssh/bootstrap.sh | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/kittens/ssh/main.py b/kittens/ssh/main.py index a8c38e452..e152feda6 100644 --- a/kittens/ssh/main.py +++ b/kittens/ssh/main.py @@ -58,7 +58,7 @@ def get_ssh_data(msg: str, shell_integration_dest: str = DEFAULT_SHELL_INTEGRATI else: from base64 import standard_b64encode encoded_data = standard_b64encode(data) - yield f"{len(encoded_data)}:".encode('ascii') + yield f"\036{len(encoded_data)}:".encode('ascii') yield encoded_data diff --git a/shell-integration/ssh/bootstrap.sh b/shell-integration/ssh/bootstrap.sh index 51209c293..64bfc5f40 100644 --- a/shell-integration/ssh/bootstrap.sh +++ b/shell-integration/ssh/bootstrap.sh @@ -7,7 +7,7 @@ cleanup_on_bootstrap_exit() { [ ! -z "$saved_tty_settings" ] && command stty "$saved_tty_settings" } -die() { echo "$*" >/dev/stderr; cleanup_on_bootstrap_exit; exit 1; } +die() { echo "$*" > /dev/stderr; cleanup_on_bootstrap_exit; exit 1; } dsc_to_kitty() { printf "\033P@kitty-$1|%s\033\\" "$(printf "%s" "$2" | base64)"; } debug() { dsc_to_kitty "print" "debug $1"; } echo_via_kitty() { dsc_to_kitty "echo" "$1"; } @@ -50,11 +50,19 @@ get_data() { # head -c reads beyond the specified number of bytes into an internal buffer on macOS # # POSIX dd works for one byte at a time but for reading X bytes it needs the GNU iflag=count_bytes - # extension. + # extension, and is anyway unsafe as it can lead to corrupt output when the read syscall is interrupted. + record_started=0 + record_separator=$(printf "\036") while :; do n=$(command dd bs=1 count=1 2> /dev/null) - if [ "$n" = ":" ]; then break; fi - size="$size$n" + if [ $record_started = 1 ]; then + if [ "$n" = ":" ]; then break; fi + size="$size$n" + else + if [ "$n" = "$record_separator" ]; then + record_started=1; + fi + fi done # using dd with bs=1 is very slow on Linux, so use head command head -c "$size" | untar