From 0f255a500235df5c9d59b735836f6106537cf452 Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Wed, 21 Aug 2024 08:13:09 -0400 Subject: separate write-tty command --- Makefile | 4 +- src/read-tty | 4 +- src/read_chars.bash | 9 +-- src/twopane.bash | 154 ++++++++++++++-------------------------------------- src/write-tty | 89 ++++++++++++++++++++++++++++++ 5 files changed, 141 insertions(+), 119 deletions(-) create mode 100644 src/write-tty diff --git a/Makefile b/Makefile index 19af34d..cda8018 100644 --- a/Makefile +++ b/Makefile @@ -10,9 +10,11 @@ ifeq (,$(socat)) prereqs += socat endif .PHONY: install deps +executables = read-tty write-tty read_chars.bash +executables_sources = $(addprefix src/,$(executables)) install: deps $(install) -v -T -- src/twopane.bash /usr/local/bin/twopane - $(install) -v -t /usr/local/bin -- src/read-tty src/read_chars.bash + $(install) -v -t /usr/local/bin -- $(executables_sources) deps: apt-install.stamp apt-install.stamp: Makefile ifneq (,$(prereqs)) diff --git a/src/read-tty b/src/read-tty index 74e2803..4821ba9 100755 --- a/src/read-tty +++ b/src/read-tty @@ -7,8 +7,8 @@ source read_chars.bash :|: export COLUMNS ( - BASH_ARGV0=read-tty-subshell + BASH_ARGV0=read_chars echo -n "$0" >/proc/$BASHPID/comm - trap 'x /bin/kill -INT -- -$BASHPID' INT + # trap 'x /bin/kill -INT -- -$BASHPID' INT read_chars ) diff --git a/src/read_chars.bash b/src/read_chars.bash index d56c1e6..5856e92 100644 --- a/src/read_chars.bash +++ b/src/read_chars.bash @@ -87,10 +87,11 @@ check_foreground() SOCAT() { - BASH_ARGV0=socat-tty-sleeper - trap 'sleep .25' SIGTSTP - trap 'kill -INT $BASHPID' SIGTTIN SIGTTOU - socat -t0 - - + #BASH_ARGV0=socat-tty-sleeper + #echo -n "$0" >/proc/$BASHPID/comm + #trap 'sleep .25' SIGTSTP + #trap 'kill -INT $BASHPID 0' SIGTTIN SIGTTOU + exec -a user-ended-connection socat - - } readchar() diff --git a/src/twopane.bash b/src/twopane.bash index 7056053..de42ba9 100755 --- a/src/twopane.bash +++ b/src/twopane.bash @@ -15,9 +15,10 @@ if [ $# = 0 ] then TOP_CMD="$SHELL -i" BOT_CMD=foreground - TOP_EXIT=prompt #BOT_CMD=start - #TOP_EXIT=restart + #TOP_EXIT=quit + #TOP_EXIT=prompt + TOP_EXIT=restart else TOP_CMD=$* BOT_CMD=start @@ -31,7 +32,7 @@ trap 'rm -r "$TWOPANE"' EXIT # STY=$(systemd-escape -p "$TWOPANE") systemd_escape_path() { - declare -g -n path="$1" result="$2" + declare -n path="$1" result="$2" result=$(realpath "$path") result=${result//-/--} result=${result//\//-} @@ -89,10 +90,8 @@ kill_screen_pane() start_screen_pane() { -# declare -g -a PANES declare -i pane="${1:-1}" (( pane > 0 )) || return -# PANES+=("$pane") if check_screen_pane "$pane" then return @@ -119,9 +118,9 @@ connect_coproc() { declare -n coproc="$1" shift - declare -g -n std1="${!coproc}_STDOUT" - declare -g -n std0="${!coproc}_STDIN" - declare -g -n opid="${!coproc}_PID" + declare -n std1="${!coproc}_STDOUT" + declare -n std0="${!coproc}_STDIN" + declare -n opid="${!coproc}_PID" if [ $# = 0 ] then @@ -136,7 +135,6 @@ connect_coproc() "$@" } 2>&$STDERR {STDERR}>&- } {STDERR}>&2 2>/dev/null - i "${!opid}=$opid" x disown fi # The copied file descriptors (unlike the original coprocess @@ -153,39 +151,48 @@ disconnect_coproc() if [ $# = 1 ] then declare -n coproc="$1" - declare -g -n std1="${!coproc}_STDOUT" - declare -g -n std0="${!coproc}_STDIN" - declare -g -n pid="${!coproc}_PID" - [ "$std0" -a "$std1" ] || return - exec {std0}<&- {std1}>&- - unset std0 std1 - x kill "$pid" - x wait -f "$pid" + declare -n std1="${!coproc}_STDOUT" + declare -n std0="${!coproc}_STDIN" + declare -n pid="${!coproc}_PID" + if [ "$std0" -o "$std1" ] + then + exec {std0}<&- {std1}>&- + fi + if [ "$pid" ] + then + x kill "$pid" + x wait -f "$pid" + fi + unset std0 std1 coproc pid fi } connect() { - connect_coproc SOCAT - i "SOCAT_PID=$SOCAT_PID" + x connect_coproc TOP_PANE } disconnect() { - i "SOCAT_STDIN=$SOCAT_STDIN SOCAT_STDOUT=$SOCAT_STDOUT SOCAT_PID=$SOCAT_PID" - x disconnect_coproc SOCAT + i "${TOP_PANE_STDIN@A} ${TOP_PANE_STDOUT@A} ${TOP_PANE_PID@A} ${TOP_PANE[@]@A}" + x disconnect_coproc TOP_PANE + if [ "$ECHOSEND" ] + then + kill $ECHOSEND_PID + unset ECHOSEND ECHOSEND_PID + fi } sendc() { - [ "${SOCAT[0]}" ] || connect - printf '%s' "$*" >&${SOCAT[1]} + [ "${TOP_PANE[0]}" ] || connect + printf '%s' "$*" >&${TOP_PANE[1]} } send() { - [ "${SOCAT[0]}" ] || connect - printf '%s\n' "$*" >&${SOCAT[1]} + [ "${TOP_PANE[0]}" ] || connect + printf '%s\n' "$*" >&${TOP_PANE[1]} } restart() @@ -222,23 +229,24 @@ tty_forward() { declare -i pid="$1" read-tty - x kill $pid + x kill "$pid" } -SOCAT() +TOP_PANE() { (exec -a bottom-pane-tty-forward socat - UNIX-CONNECT:"$TWOPANE"/socket,forever) case "$TOP_EXIT" in restart ) start_screen_pane 1 "$@" + kill -USR1 $$ ;; quit ) quit ;; prompt | * ) + focus bottom ;; esac - x screen -X quit } echosend() @@ -247,11 +255,11 @@ echosend() declare -n pid="${!fd}_PID" if ! [ "$fd" ] then - connect_coproc SOCAT - i "SOCAT_PID=$SOCAT_PID" + x connect + i "${TOP_PANE_STDIN@A} ${TOP_PANE_STDOUT@A} ${TOP_PANE_PID@A} ${TOP_PANE[@]@A}" exec {fd}> >( - (exec -a echosend socat - fd:${SOCAT_STDIN?e}!!-) | - tee >(output_filter) >&${SOCAT_STDOUT?e} + (exec -a echosend socat - fd:${TOP_PANE_STDIN?e}!!-) | + tee >(write-tty) >&${TOP_PANE_STDOUT?e} ) pid=$! fi @@ -269,7 +277,7 @@ background() { start_screen_pane 1 "$@" focus bottom - echosend ECHOSEND + x echosend ECHOSEND { eval "tty_forward $ECHOSEND_PID &" } >&$ECHOSEND @@ -287,7 +295,6 @@ foreground() check_tty_reader || background focus top fg %tty_forward >/dev/null - #disconnect focus bottom } @@ -296,16 +303,13 @@ foreground_loop() while true do foreground - x kill %tty_forward 2>/dev/null case "$TOP_EXIT" in restart ) - x kill -INT $TTY_READER_PID $ECHOSEND_PID start_screen_pane "$@" continue ;; quit ) exit ;; prompt | * ) - x kill -INT $TTY_READER_PID $ECHOSEND_PID break ;; esac @@ -327,79 +331,6 @@ focus() screen -X focus "$@" } -output_filter() -{ - tokenize | colorize | soft_cursor -} - -chr() -{ - declare -i n="$*" - printf "\\$(printf %o "$n")" -} - -colorize() -{ - while read -r - do - case "$REPLY" in - \\[0-7][0-7][0-7] ) ;; - * ) - printf '%s\n' "$REPLY" - continue - ;; - esac - declare -i c=8#"${REPLY#?}" - if (( c > 128 + 127 )) - then - : - elif (( c > 128 + 32 )) - then - printf -v REPLY "M-$(chr c - 128)" - elif (( c > 127 )) - then - printf -v REPLY "M-^$(chr c - 128 + 64)" - elif (( c < 32 )) - then - printf -v REPLY "^$(chr c + 64)" - fi - printf $'\e[106m%s\e[m\n' "$REPLY" - done -} - -tokenize() -{ - while read -r -N1 - do - if [[ "$REPLY" =~ [[:print:]] ]] - then - # Output one printable character per line. It may be a - # multibyte unicode character. - printf '%s\n' "$REPLY" - continue - else - # If it is a non-printable, then we output a - # multi-character line. In this case we colorize it - # later so that it won't be confused with multiple - # printable characters in the . - printf '\\%.3o\n' "'$REPLY" - continue - fi - done -} - -soft_cursor() -{ - FMT=$'%s \b\e[%sm \e[m\b' - REPLY= - color=101 - while printf "$FMT" "$REPLY" "$color" - do - read -r || break - let '++color <= 105' || color=101 - done -} - resize() { screen -X resize "$@" @@ -411,8 +342,7 @@ our_bashrc_main() set -f set -o pipefail #trap 'focus bottom; resize 90%; read -p "Exit> "; quit' EXIT - #trap 'echo USR1 >&2; focus bottom; x kill -INT %tty_forward $TTY_READER_PID $ECHOSEND_PID' USR1 - trap 'quit' USR1 + trap 'disconnect; focus bottom;' USR1 export PS1="$BOT_TITLE\\\$ " } diff --git a/src/write-tty b/src/write-tty new file mode 100644 index 0000000..fbe62ea --- /dev/null +++ b/src/write-tty @@ -0,0 +1,89 @@ +#!/bin/bash +BASH_ARGV0=write-tty +echo -n "$0" >/proc/$BASHPID/comm + +output_filter() +{ + tokenize | colorize | soft_cursor +} + +chr() +{ + declare -i n="$*" + printf "\\$(printf %o "$n")" +} + +colorize() +{ + BASH_ARGV0=colorize + echo -n "$0" >/proc/$BASHPID/comm + while read -r + do + case "$REPLY" in + \\[0-7][0-7][0-7] ) ;; + * ) + printf '%s\n' "$REPLY" + continue + ;; + esac + declare -i c=8#"${REPLY#?}" + if (( c > 128 + 127 )) + then + : + elif (( c > 128 + 32 )) + then + printf -v REPLY "M-$(chr c - 128)" + elif (( c > 127 )) + then + printf -v REPLY "M-^$(chr c - 128 + 64)" + elif (( c < 32 )) + then + printf -v REPLY "^$(chr c + 64)" + fi + printf $'\e[106m%s\e[m\n' "$REPLY" + done +} + +tokenize() +{ + BASH_ARGV0=tokenize + echo -n "$0" >/proc/$BASHPID/comm + while read -r -N1 + do + if [[ "$REPLY" =~ [[:print:]] ]] + then + # Output one printable character per line. It may be a + # multibyte unicode character. + printf '%s\n' "$REPLY" + continue + else + # If it is a non-printable, then we output a + # multi-character line. In this case we colorize it + # later so that it won't be confused with multiple + # printable characters in the . + printf '\\%.3o\n' "'$REPLY" + continue + fi + done +} + +soft_cursor() +{ + BASH_ARGV0=soft_cursor + echo -n "$0" >/proc/$BASHPID/comm + FMT=$'%s \b\e[%sm \e[m\b' + REPLY= + color=101 + while printf "$FMT" "$REPLY" "$color" + do + read -r || break + let '++color <= 105' || color=101 + done +} + +if [ -t 1 ] +then + output_filter +else + exec -a write-tty-raw socat - - +fi -- cgit v1.2.3