chiark / gitweb /
bin/outbound: Change how we wait for SSH tunnels to end. master
authorMark Wooding <mdw@distorted.org.uk>
Wed, 6 May 2015 17:05:14 +0000 (18:05 +0100)
committerMark Wooding <mwooding@good.com>
Wed, 6 May 2015 17:08:12 +0000 (18:08 +0100)
The old method didn't actually work.  Instead, the shell just got
stuck waiting for the pipe to open and never did anything useful.

New approach: make a pipe, and wait for it to close for reading, using
a backgrounded cat(1); have the SSH control-master process write its
(empty) stdout to the pipe; and, finally, wait for the cat(1) to
finish.

bin/outbound

index 5ed160d..ac810aa 100755 (executable)
@@ -63,6 +63,9 @@ daemon () {
   ## Initial delay.
   delay=0
 
+  ## Not waiting on a pipe yet.
+  kidcat=nil
+
   ## Keep the connection up for as long as we can.
   while [ -f "$host.pid" ]; do
 
@@ -80,9 +83,18 @@ daemon () {
        ;;
     esac
 
+    ## Prepare a pipe so that we can wait for SSH to finish.  This is a
+    ## rotten hack.
+    case $kidcat in
+      nil) ;;
+      *) kill $kidcat >/dev/null 2>&1 || :; kidcat=nil ;;
+    esac
+    rm -f "$host.pipe"; mkfifo -m600 "$host.pipe"
+    cat $host.pipe >/dev/null& kidcat=$!
+
     ## Start a new connection.
     writefile "$host.state" starting
-    if ! runssh -MNnf "$host" >/dev/null; then continue; fi
+    if ! runssh -MNnf "$host" >"$host.pipe"; then continue; fi
     if ! runssh -Ocheck "$host" >/dev/null 2>&1; then
       echo "connection to $host apparently stillborn"
       continue
@@ -90,13 +102,10 @@ daemon () {
     writefile "$host.state" connected
     delay=0
 
-    ## Wait until it gets torn down.  The chicanery with a pipe is because
-    ## the ssh process will continue until either it gets disconnected from
-    ## the server or stdin closes -- so we have to arrange that stdin doesn't
-    ## close.  Thanks to Richard Kettlewell for the suggestion.
-    rm -f "$host.pipe"; mkfifo -m400 "$host.pipe"
-    runssh -N "$host" >/dev/null <"$host.pipe" || :
+    ## Wait until it gets torn down.
+    wait $kidcat >/dev/null 2>&1 || :
     rm -f "$host.pipe"
+    clobber
     writefile "$host.state" disconnected
   done
 }