diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/twopane.bash | 72 |
1 files changed, 51 insertions, 21 deletions
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() | |||
280 | printf '%s\n' "$*" >&${TOP_PANE_OUT?Internal error} | 280 | printf '%s\n' "$*" >&${TOP_PANE_OUT?Internal error} |
281 | } | 281 | } |
282 | 282 | ||
283 | check_restart_sink() | ||
284 | { | ||
285 | (( $# > 0 )) || set -- SINK | ||
286 | declare -n sinkfd="$1" | ||
287 | declare -n pid="${!sinkfd}_PID" | ||
288 | [ "$pid" ] || return | ||
289 | kill -0 "$pid" &>/dev/null || | ||
290 | start_sink_process "${!sinkfd}" | ||
291 | } | ||
292 | |||
283 | tty_forward() | 293 | tty_forward() |
284 | { | 294 | { |
285 | printf '%d\n' "$BASHPID" > "$TWOPANE"/tty_forward.pid | 295 | printf '%d\n' "$BASHPID" > "$TWOPANE"/tty_forward.pid |
@@ -305,7 +315,7 @@ TOP_PANE() | |||
305 | esac | 315 | esac |
306 | } | 316 | } |
307 | 317 | ||
308 | magic_fifo() | 318 | magic_fifo_sink() |
309 | { | 319 | { |
310 | # Some bash magic from superuser.com. | 320 | # Some bash magic from superuser.com. |
311 | # Use two PIDs instead of one inode to make fifo. (Not just | 321 | # Use two PIDs instead of one inode to make fifo. (Not just |
@@ -323,46 +333,63 @@ magic_fifo() | |||
323 | quiet_bg "${@:2}" <&"$fd_in" | 333 | quiet_bg "${@:2}" <&"$fd_in" |
324 | } | 334 | } |
325 | 335 | ||
326 | ordinary_fifo() | 336 | # This function serves to replace bash's builtin >() syntax. That |
337 | # syntax does not allow the asynchronous command to be subject to | ||
338 | # interactive job control. The actual bash implementation of >() uses a | ||
339 | # /proc/fd/ trick on Linux to avoid mkfifo. | ||
340 | fifo_sink() | ||
327 | { | 341 | { |
342 | (( $# > 0 )) || set -- SINK | ||
343 | (( $# > 1 )) || set -- "$1" "$1" | ||
328 | declare -n fd_out="$1" | 344 | declare -n fd_out="$1" |
329 | local fifo | 345 | local fifo fd_in |
330 | fifo=$TWOPANE/sink_${!fd}.fifo | 346 | fifo=${TWOPANE:-$TMP}/sink_${!fd_out}.$$.fifo |
331 | mkfifo "$fifo" | 347 | mkfifo "$fifo" || return |
348 | |||
332 | exec {fd_out}<>"$fifo" | 349 | exec {fd_out}<>"$fifo" |
350 | fd_in=$fd_out | ||
333 | rm "$fifo" | 351 | rm "$fifo" |
334 | quiet_bg "${@:2}" <&"$fd_out" | 352 | quiet_bg "${@:2}" <&"$fd_in" {fd_in}<&- |
353 | return | ||
335 | } | 354 | } |
336 | 355 | ||
337 | connect_sink() | 356 | connect_sink() |
338 | { | 357 | { |
339 | (( $# > 0 )) || set -- SINK | 358 | (( $# > 0 )) || set -- SINK |
340 | declare -n fd="$1" | 359 | (( $# > 1 )) || set -- "$1" "$1" |
341 | declare -n pid="${!fd}_PID" | 360 | declare -n sinkfd="$1" |
361 | declare -n pid="${!sinkfd}_PID" | ||
362 | declare -n sinkstartcmd="${!sinkfd}_start_command" | ||
363 | sinkstartcmd=$(printf '%q\n' "${@:2}") | ||
342 | if [ "$pid" ] | 364 | if [ "$pid" ] |
343 | then | 365 | then |
344 | i "sink already running: ${!fd}" | 366 | i "sink already running: ${!sinkfd}" |
345 | return | ||
346 | fi | ||
347 | i "sink starting: ${!fd}" | ||
348 | |||
349 | if false && mountpoint -q /proc | ||
350 | then | ||
351 | magic_fifo fd "${@:2}" | ||
352 | else | 367 | else |
353 | ordinary_fifo fd "${@:2}" | 368 | start_sink_process "${!sinkfd}" |
354 | fi | 369 | fi |
370 | } | ||
371 | |||
372 | start_sink_process() | ||
373 | { | ||
374 | (( $# > 0 )) || set -- SINK | ||
375 | declare -n sinkfd="$1" | ||
376 | declare -n sinkstartcmd="${!sinkfd}_start_command" | ||
377 | declare -a cmd | ||
378 | cmd=($sinkstartcmd) | ||
379 | (( ${#cmd[@]} > 0 )) || return | ||
380 | i "sink starting: ${!sinkfd}" | ||
381 | fifo_sink "${!sinkfd}" "${cmd[@]}" | ||
355 | pid=$! | 382 | pid=$! |
356 | } | 383 | } |
357 | 384 | ||
358 | disconnect_sink() | 385 | disconnect_sink() |
359 | { | 386 | { |
360 | (( $# > 0 )) || set -- SINK | 387 | (( $# > 0 )) || set -- SINK |
361 | declare -n fd="$1" | 388 | declare -n sinkfd="$1" |
362 | [ "$fd" ] || return | 389 | [ "$fd" ] || return |
363 | declare -n pid="${!fd}_PID" | 390 | declare -n pid="${!sinkfd}_PID" |
364 | i "sink stopping: ${!fd}" | 391 | i "sink stopping: ${!sinkfd}" |
365 | exec {fd}>&- | 392 | exec {sinkfd}>&- |
366 | kill $pid 2>/dev/null | 393 | kill $pid 2>/dev/null |
367 | unset fd pid | 394 | unset fd pid |
368 | } | 395 | } |
@@ -466,6 +493,8 @@ killpgrp() | |||
466 | 493 | ||
467 | prompt_command() | 494 | prompt_command() |
468 | { | 495 | { |
496 | check_restart_sink ECHOSEND | ||
497 | |||
469 | [ "$TOP_EXIT" = 'restart' ] || return 0 | 498 | [ "$TOP_EXIT" = 'restart' ] || return 0 |
470 | 499 | ||
471 | if [ "$SIG" = INT ] | 500 | if [ "$SIG" = INT ] |
@@ -514,6 +543,7 @@ our_bashrc_main() | |||
514 | trap 'SIGINT' INT | 543 | trap 'SIGINT' INT |
515 | trap '! [ "$DEBUG" ] || read -p "Exit> "; quit' EXIT | 544 | trap '! [ "$DEBUG" ] || read -p "Exit> "; quit' EXIT |
516 | export PS1="$BOT_TITLE\\\$ " | 545 | export PS1="$BOT_TITLE\\\$ " |
546 | export PS4='+ \t$LINENO\t ' | ||
517 | } | 547 | } |
518 | 548 | ||
519 | save_file bashrc <<. | 549 | save_file bashrc <<. |