with-authinfo-kludge: Add machinery to restore signals in child processes.
[with-authinfo-kludge] / with-authinfo-kludge
index 112668e..4317d8d 100755 (executable)
 ### along with this program; if not, write to the Free Software Foundation,
 ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
-## things to do
-##
-## pidfiles
-
-my $VERSION = "0.1.0~unfinished";
+my $VERSION = "0.1.0";
 
 use strict;
 
@@ -167,10 +163,30 @@ sub lockedp ($) {
   return $l->l_type != F_UNLCK;
 }
 
+sub write_to_file ($$) {
+  my ($file, $contents) = @_;
+  my $new = "$file.new";
+  open my $fh, ">", $new or sysfail "couldn't open `$new' for writing: $!";
+  print $fh $contents;
+  $fh->flush && !$fh->error && close $fh
+    or sysfail "failed to write to `$new': $!";
+  rename $new, $file or sysfail "failed to rename `$new' to `$file': $!";
+}
+
+my %OLDSIGS;
+sub set_sighandler ($$) {
+  my ($sig, $handler) = @_;
+  unless (exists $OLDSIGS{$sig}) { $OLDSIGS{$sig} = $SIG{$sig}; }
+  $SIG{$sig} = $handler;
+}
+
 my $INKIDP = 0;
 sub myfork () {
   my $kid = fork;
-  if (defined $kid && !$kid) { $INKIDP = 1; }
+  if (defined $kid && !$kid) {
+    $INKIDP = 1;
+    for my $sig (keys %OLDSIGS) { $SIG{$sig} = $OLDSIGS{$sig}; }
+  }
   return $kid;
 }
 
@@ -663,8 +679,8 @@ sub server_listen ($) {
 
     ## The `-L' option sets up the tunnel that we actually wanted.  The `-v'
     ## makes SSH spew stuff to stdout, which might be useful if you're
-    ## debugging.  .  The `-S' detaches OpenSSH from any control master
-    ## things which might be going on, because they tend to interfere with
+    ## debugging.  The `-S' detaches OpenSSH from any control master things
+    ## which might be going on, because they tend to interfere with
     ## forwarding (and, besides, the existing master won't be under the same
     ## noip configuration).  The `echo' will let us know that it's started
     ## up, and the `read' will keep the tunnel open until we close our end,
@@ -693,6 +709,7 @@ EOF
     $s->{"_ssh_stdin"} = $win;
     $s->{"_ssh_stdout"} = $rout;
     $KIDMAP{$kid} = [$s, "SSH tunnel"];
+    write_to_file "$SESSDIR/ssh-$server.pid", "$kid\n";
   }
 }
 
@@ -721,7 +738,7 @@ sub wait_for_ssh () {
     my ($n, $t) = select my $rfd_out = $rfd_in, undef, undef, undef;
     if ($n >= 0) { }
     elsif ($! == EINTR) { next SELECT; }
-    else {  sysfail "select failed: $!"; }
+    else { sysfail "select failed: $!"; }
     FD: for my $fd (keys %fd) {
       next FD unless vec $rfd_out, $fd, 1;
       my ($sk, $s) = @{$fd{$fd}};
@@ -740,7 +757,7 @@ sub wait_for_ssh () {
   else { inform "  all tunnels started ok"; }
 }
 
-$SIG{"CHLD"} = sub {
+set_sighandler "CHLD", sub {
   KID: for (;;) {
     defined (my $kid = waitpid -1, WNOHANG)
       or sysfail "failed to reap child: $!";
@@ -782,6 +799,7 @@ sub run_client (@) {
     exec @args or sysfail "failed to exec `$prog': $!";
   }
   $CLIENTKID = $kid;
+  write_to_file "$SESSDIR/client.pid", "$kid\n";
 }
 
 sub accept_loop () {
@@ -791,7 +809,7 @@ sub accept_loop () {
     my ($n, $t) = select my $rfd_out = $rfd_in, undef, undef, undef;
     if ($n >= 0) { }
     elsif ($! == EINTR) { next SELECT; }
-    else {  sysfail "select failed: $!"; }
+    else { sysfail "select failed: $!"; }
     FD: for my $fd (keys %SERVMAP) {
       next FD unless vec $rfd_out, $fd, 1;
       my ($s, $a, $sk) = @{$SERVMAP{$fd}};