diff options
author | Andrew Cady <d@jerkface.net> | 2024-08-21 17:42:07 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2024-08-21 20:47:18 -0400 |
commit | 98497a1a5e4eeba4d003c80e609ca2924148303f (patch) | |
tree | f6aee7399d81e3a7225712d79278fc82d55075a8 /src/twopane.bash | |
parent | 0f255a500235df5c9d59b735836f6106537cf452 (diff) |
still working
Diffstat (limited to 'src/twopane.bash')
-rwxr-xr-x | src/twopane.bash | 132 |
1 files changed, 79 insertions, 53 deletions
diff --git a/src/twopane.bash b/src/twopane.bash index de42ba9..e2b12c9 100755 --- a/src/twopane.bash +++ b/src/twopane.bash | |||
@@ -17,8 +17,8 @@ then | |||
17 | BOT_CMD=foreground | 17 | BOT_CMD=foreground |
18 | #BOT_CMD=start | 18 | #BOT_CMD=start |
19 | #TOP_EXIT=quit | 19 | #TOP_EXIT=quit |
20 | #TOP_EXIT=prompt | 20 | TOP_EXIT=prompt |
21 | TOP_EXIT=restart | 21 | #TOP_EXIT=restart |
22 | else | 22 | else |
23 | TOP_CMD=$* | 23 | TOP_CMD=$* |
24 | BOT_CMD=start | 24 | BOT_CMD=start |
@@ -105,7 +105,7 @@ start_screen_pane() | |||
105 | TOP_TITLE="Command: ${*@Q}" | 105 | TOP_TITLE="Command: ${*@Q}" |
106 | screen -X focus top | 106 | screen -X focus top |
107 | screen -X screen -ln -t "$TOP_TITLE" 1 "$@" | 107 | screen -X screen -ln -t "$TOP_TITLE" 1 "$@" |
108 | screen -p "$pane" -X exec .!. bash -c 'exec -a top-pane-tty-forward socat UNIX-LISTEN:"$TWOPANE"/socket STDIN,cfmakeraw!!STDOUT' | 108 | screen -p "$pane" -X exec .!. bash -c 'exec -a top-pane-tty-forward socat UNIX-LISTEN:"$TWOPANE"/socket STDIN,cfmakeraw,opost=1,onlcr=1!!STDOUT' |
109 | } | 109 | } |
110 | 110 | ||
111 | restart_screen_pane() | 111 | restart_screen_pane() |
@@ -135,7 +135,7 @@ connect_coproc() | |||
135 | "$@" | 135 | "$@" |
136 | } 2>&$STDERR {STDERR}>&- | 136 | } 2>&$STDERR {STDERR}>&- |
137 | } {STDERR}>&2 2>/dev/null | 137 | } {STDERR}>&2 2>/dev/null |
138 | x disown | 138 | disown |
139 | fi | 139 | fi |
140 | # The copied file descriptors (unlike the original coprocess | 140 | # The copied file descriptors (unlike the original coprocess |
141 | # file descriptors, in ${coproc[0]} and ${coproc[1]}) can be | 141 | # file descriptors, in ${coproc[0]} and ${coproc[1]}) can be |
@@ -148,37 +148,36 @@ connect_coproc() | |||
148 | 148 | ||
149 | disconnect_coproc() | 149 | disconnect_coproc() |
150 | { | 150 | { |
151 | if [ $# = 1 ] | 151 | [ $# = 1 ] || return |
152 | declare -n coproc="$1" | ||
153 | declare -n std0="${!coproc}_STDIN" | ||
154 | declare -n std1="${!coproc}_STDOUT" | ||
155 | declare -n pid="${!coproc}_PID" | ||
156 | if [ "$std0" -o "$std1" ] | ||
152 | then | 157 | then |
153 | declare -n coproc="$1" | 158 | exec {std0}<&- {std1}>&- |
154 | declare -n std1="${!coproc}_STDOUT" | ||
155 | declare -n std0="${!coproc}_STDIN" | ||
156 | declare -n pid="${!coproc}_PID" | ||
157 | if [ "$std0" -o "$std1" ] | ||
158 | then | ||
159 | exec {std0}<&- {std1}>&- | ||
160 | fi | ||
161 | if [ "$pid" ] | ||
162 | then | ||
163 | x kill "$pid" | ||
164 | x wait -f "$pid" | ||
165 | fi | ||
166 | unset std0 std1 coproc pid | ||
167 | fi | 159 | fi |
160 | if [ "$pid" ] | ||
161 | then | ||
162 | kill "$pid" 2>/dev/null | ||
163 | wait -f "$pid" 2>/dev/null | ||
164 | fi | ||
165 | unset coproc std0 std1 pid | ||
168 | } | 166 | } |
169 | 167 | ||
170 | connect() | 168 | connect() |
171 | { | 169 | { |
172 | x connect_coproc TOP_PANE | 170 | connect_coproc TOP_PANE |
173 | } | 171 | } |
174 | 172 | ||
175 | disconnect() | 173 | disconnect() |
176 | { | 174 | { |
177 | i "${TOP_PANE_STDIN@A} ${TOP_PANE_STDOUT@A} ${TOP_PANE_PID@A} ${TOP_PANE[@]@A}" | 175 | : "${TOP_PANE_STDIN@A} ${TOP_PANE_STDOUT@A} ${TOP_PANE_PID@A} ${TOP_PANE[@]@A}" |
178 | x disconnect_coproc TOP_PANE | 176 | disconnect_coproc TOP_PANE |
179 | if [ "$ECHOSEND" ] | 177 | if [ "$ECHOSEND" ] |
180 | then | 178 | then |
181 | kill $ECHOSEND_PID | 179 | exec {ECHOSEND}>&- |
180 | kill $ECHOSEND_PID 2>/dev/null | ||
182 | unset ECHOSEND ECHOSEND_PID | 181 | unset ECHOSEND ECHOSEND_PID |
183 | fi | 182 | fi |
184 | } | 183 | } |
@@ -207,9 +206,9 @@ start() | |||
207 | 206 | ||
208 | check_tty_reader() | 207 | check_tty_reader() |
209 | { | 208 | { |
210 | [ "$TTY_READER_PID" ] || return | 209 | [ "$TTY_FORWARD_PID" ] || return |
211 | TTY_READER_JOBSPEC=$(jobs -sl | pid_to_jobspec "$TTY_READER_PID") | 210 | TTY_FORWARD_JOBSPEC=$(jobs -sl | pid_to_jobspec "$TTY_FORWARD_PID") |
212 | [ "$TTY_READER_JOBSPEC" ] | 211 | [ "$TTY_FORWARD_JOBSPEC" ] |
213 | } | 212 | } |
214 | 213 | ||
215 | pid_to_jobspec() | 214 | pid_to_jobspec() |
@@ -227,20 +226,26 @@ pid_to_jobspec() | |||
227 | 226 | ||
228 | tty_forward() | 227 | tty_forward() |
229 | { | 228 | { |
230 | declare -i pid="$1" | 229 | printf '%d\n' "$BASHPID" > "$TWOPANE"/tty_forward.pid |
231 | read-tty | 230 | read-tty |
232 | x kill "$pid" | 231 | } |
232 | |||
233 | kill_tty_forward() | ||
234 | { | ||
235 | read pid < "$TWOPANE"/tty_forward.pid | ||
236 | /bin/kill -INT -- -$pid 2>/dev/null | ||
233 | } | 237 | } |
234 | 238 | ||
235 | TOP_PANE() | 239 | TOP_PANE() |
236 | { | 240 | { |
237 | (exec -a bottom-pane-tty-forward socat - UNIX-CONNECT:"$TWOPANE"/socket,forever) | 241 | (exec -a bottom-pane-tty-forward socat - UNIX-CONNECT:"$TWOPANE"/socket,forever) |
242 | kill_tty_forward | ||
238 | case "$TOP_EXIT" in | 243 | case "$TOP_EXIT" in |
239 | restart ) | 244 | restart ) |
240 | start_screen_pane 1 "$@" | ||
241 | kill -USR1 $$ | 245 | kill -USR1 $$ |
242 | ;; | 246 | ;; |
243 | quit ) | 247 | quit ) |
248 | kill -INT $$ | ||
244 | quit | 249 | quit |
245 | ;; | 250 | ;; |
246 | prompt | * ) | 251 | prompt | * ) |
@@ -249,20 +254,24 @@ TOP_PANE() | |||
249 | esac | 254 | esac |
250 | } | 255 | } |
251 | 256 | ||
252 | echosend() | 257 | sink() |
253 | { | 258 | { |
254 | declare -n fd="$1" | 259 | declare -n fd="$1" |
255 | declare -n pid="${!fd}_PID" | 260 | declare -n pid="${!fd}_PID" |
256 | if ! [ "$fd" ] | 261 | if [ "$fd" ] |
257 | then | 262 | then |
258 | x connect | 263 | exec {fd}>&- |
259 | i "${TOP_PANE_STDIN@A} ${TOP_PANE_STDOUT@A} ${TOP_PANE_PID@A} ${TOP_PANE[@]@A}" | 264 | kill $pid 2>/dev/null |
260 | exec {fd}> >( | 265 | unset fd pid |
261 | (exec -a echosend socat - fd:${TOP_PANE_STDIN?e}!!-) | | ||
262 | tee >(write-tty) >&${TOP_PANE_STDOUT?e} | ||
263 | ) | ||
264 | pid=$! | ||
265 | fi | 266 | fi |
267 | exec {fd}> >("${@:2}") | ||
268 | pid=$! | ||
269 | } | ||
270 | |||
271 | echo_sender() | ||
272 | { | ||
273 | (exec -a echo_sender socat - fd:${TOP_PANE_STDIN?$0: Internal error}!!-) | | ||
274 | tee >(write-tty) >&${TOP_PANE_STDOUT?$0: Internal error} | ||
266 | } | 275 | } |
267 | 276 | ||
268 | quiet_bg() | 277 | quiet_bg() |
@@ -275,47 +284,59 @@ quiet_bg() | |||
275 | 284 | ||
276 | background() | 285 | background() |
277 | { | 286 | { |
287 | disconnect | ||
278 | start_screen_pane 1 "$@" | 288 | start_screen_pane 1 "$@" |
279 | focus bottom | 289 | focus bottom |
280 | x echosend ECHOSEND | 290 | connect |
281 | { | 291 | sink ECHOSEND echo_sender |
282 | eval "tty_forward $ECHOSEND_PID &" | 292 | quiet_bg tty_forward >&$ECHOSEND |
283 | } >&$ECHOSEND | 293 | TTY_FORWARD_PID=$! |
284 | TTY_READER_PID=$! | 294 | printf '%d\n' "$TTY_FORWARD_PID" > "$TWOPANE"/tty_forward.pid |
285 | printf '%s\n' \ | 295 | printf '%s\n' \ |
286 | "#!/bin/bash" \ | 296 | "#!/bin/bash" \ |
287 | "kill -TSTP $TTY_READER_PID" \ | 297 | "kill -TSTP $TTY_FORWARD_PID" \ |
288 | "screen -X focus bottom" \ | 298 | "screen -X focus bottom" \ |
289 | > "$TWOPANE"/unforward | 299 | > "$TWOPANE"/unforward |
290 | chmod +x "$TWOPANE"/unforward | 300 | chmod +x "$TWOPANE"/unforward |
291 | } | 301 | } |
292 | 302 | ||
293 | foreground() | 303 | foreground_once() |
294 | { | 304 | { |
295 | check_tty_reader || background | 305 | check_tty_reader || background "$@" |
296 | focus top | 306 | focus top |
297 | fg %tty_forward >/dev/null | 307 | while jobs %tty_forward >/dev/null 2>&1 |
298 | focus bottom | 308 | do |
309 | fg %tty_forward >/dev/null | ||
310 | kill %tty_forward 2>/dev/null | ||
311 | done | ||
299 | } | 312 | } |
300 | 313 | ||
301 | foreground_loop() | 314 | foreground_loop() |
302 | { | 315 | { |
303 | while true | 316 | while true |
304 | do | 317 | do |
305 | foreground | 318 | foreground_once "$@" |
306 | case "$TOP_EXIT" in | 319 | case "$TOP_EXIT" in |
307 | restart ) | 320 | restart ) |
308 | start_screen_pane "$@" | 321 | start_screen_pane "$@" |
309 | continue ;; | 322 | continue |
323 | ;; | ||
310 | quit ) | 324 | quit ) |
311 | exit ;; | 325 | quit |
326 | ;; | ||
312 | prompt | * ) | 327 | prompt | * ) |
313 | break | 328 | kill -INT 0 |
329 | break # unreached | ||
314 | ;; | 330 | ;; |
315 | esac | 331 | esac |
316 | done | 332 | done |
317 | } | 333 | } |
318 | 334 | ||
335 | foreground() | ||
336 | { | ||
337 | foreground_loop "$@" | ||
338 | } | ||
339 | |||
319 | twopane() | 340 | twopane() |
320 | { | 341 | { |
321 | start "$@" | 342 | start "$@" |
@@ -336,13 +357,18 @@ resize() | |||
336 | screen -X resize "$@" | 357 | screen -X resize "$@" |
337 | } | 358 | } |
338 | 359 | ||
360 | SIGUSR1() | ||
361 | { | ||
362 | i "${BASH_COMMAND@A}" | ||
363 | } | ||
364 | |||
339 | our_bashrc_main() | 365 | our_bashrc_main() |
340 | { | 366 | { |
341 | set -m | 367 | set -m |
342 | set -f | 368 | set -f |
343 | set -o pipefail | 369 | set -o pipefail |
344 | #trap 'focus bottom; resize 90%; read -p "Exit> "; quit' EXIT | 370 | #trap 'focus bottom; resize 90%; read -p "Exit> "; quit' EXIT |
345 | trap 'disconnect; focus bottom;' USR1 | 371 | trap 'SIGUSR1' USR1 |
346 | export PS1="$BOT_TITLE\\\$ " | 372 | export PS1="$BOT_TITLE\\\$ " |
347 | } | 373 | } |
348 | 374 | ||