From 2f9fde5ac8a14ba6be7c5ec2ef95735fd94ec73c Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Wed, 28 Aug 2024 21:55:33 -0400 Subject: auto-restart ECHOSEND --- src/twopane.bash | 72 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/twopane.bash b/src/twopane.bash index fe61dc2..990035d 100755 --- a/src/twopane.bash +++ b/src/twopane.bash @@ -280,6 +280,16 @@ send() printf '%s\n' "$*" >&${TOP_PANE_OUT?Internal error} } +check_restart_sink() +{ + (( $# > 0 )) || set -- SINK + declare -n sinkfd="$1" + declare -n pid="${!sinkfd}_PID" + [ "$pid" ] || return + kill -0 "$pid" &>/dev/null || + start_sink_process "${!sinkfd}" +} + tty_forward() { printf '%d\n' "$BASHPID" > "$TWOPANE"/tty_forward.pid @@ -305,7 +315,7 @@ TOP_PANE() esac } -magic_fifo() +magic_fifo_sink() { # Some bash magic from superuser.com. # Use two PIDs instead of one inode to make fifo. (Not just @@ -323,46 +333,63 @@ magic_fifo() quiet_bg "${@:2}" <&"$fd_in" } -ordinary_fifo() +# This function serves to replace bash's builtin >() syntax. That +# syntax does not allow the asynchronous command to be subject to +# interactive job control. The actual bash implementation of >() uses a +# /proc/fd/ trick on Linux to avoid mkfifo. +fifo_sink() { + (( $# > 0 )) || set -- SINK + (( $# > 1 )) || set -- "$1" "$1" declare -n fd_out="$1" - local fifo - fifo=$TWOPANE/sink_${!fd}.fifo - mkfifo "$fifo" + local fifo fd_in + fifo=${TWOPANE:-$TMP}/sink_${!fd_out}.$$.fifo + mkfifo "$fifo" || return + exec {fd_out}<>"$fifo" + fd_in=$fd_out rm "$fifo" - quiet_bg "${@:2}" <&"$fd_out" + quiet_bg "${@:2}" <&"$fd_in" {fd_in}<&- + return } connect_sink() { (( $# > 0 )) || set -- SINK - declare -n fd="$1" - declare -n pid="${!fd}_PID" + (( $# > 1 )) || set -- "$1" "$1" + declare -n sinkfd="$1" + declare -n pid="${!sinkfd}_PID" + declare -n sinkstartcmd="${!sinkfd}_start_command" + sinkstartcmd=$(printf '%q\n' "${@:2}") if [ "$pid" ] then - i "sink already running: ${!fd}" - return - fi - i "sink starting: ${!fd}" - - if false && mountpoint -q /proc - then - magic_fifo fd "${@:2}" + i "sink already running: ${!sinkfd}" else - ordinary_fifo fd "${@:2}" + start_sink_process "${!sinkfd}" fi +} + +start_sink_process() +{ + (( $# > 0 )) || set -- SINK + declare -n sinkfd="$1" + declare -n sinkstartcmd="${!sinkfd}_start_command" + declare -a cmd + cmd=($sinkstartcmd) + (( ${#cmd[@]} > 0 )) || return + i "sink starting: ${!sinkfd}" + fifo_sink "${!sinkfd}" "${cmd[@]}" pid=$! } disconnect_sink() { (( $# > 0 )) || set -- SINK - declare -n fd="$1" + declare -n sinkfd="$1" [ "$fd" ] || return - declare -n pid="${!fd}_PID" - i "sink stopping: ${!fd}" - exec {fd}>&- + declare -n pid="${!sinkfd}_PID" + i "sink stopping: ${!sinkfd}" + exec {sinkfd}>&- kill $pid 2>/dev/null unset fd pid } @@ -466,6 +493,8 @@ killpgrp() prompt_command() { + check_restart_sink ECHOSEND + [ "$TOP_EXIT" = 'restart' ] || return 0 if [ "$SIG" = INT ] @@ -514,6 +543,7 @@ our_bashrc_main() trap 'SIGINT' INT trap '! [ "$DEBUG" ] || read -p "Exit> "; quit' EXIT export PS1="$BOT_TITLE\\\$ " + export PS4='+ \t$LINENO\t ' } save_file bashrc <<. -- cgit v1.2.3