chiark / gitweb /
totally revamp remote error handling
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 2972a9ece86a8e52db94e2bf73fe7e8734e2493b..6ec99acb31c13b998bc7c3dcdd4c13620dcd7b03 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -1430,13 +1430,18 @@ sub cmd_remote_push_responder {
 }
 
 our $i_tmp;
+our $i_child_pid;
 
 sub i_cleanup {
     local ($@);
-    return unless defined $i_tmp;
-    return if defined $initiator_tempdir;
-    changedir "/";
-    eval { rmtree $i_tmp; };
+    if ($i_child_pid) {
+       printdebug "(killing remote child $i_child_pid)\n";
+       kill 15, $i_child_pid;
+    }
+    if (defined $i_tmp && !defined $initiator_tempdir) {
+       changedir "/";
+       eval { rmtree $i_tmp; };
+    }
 }
 
 END { i_cleanup(); }
@@ -1465,27 +1470,34 @@ sub cmd_rpush {
     push @rdgit, @ARGV;
     my @cmd = (@ssh, $host, shellquote @rdgit);
     printcmd \*DEBUG,$debugprefix."+",@cmd;
-    eval {
-       if (defined $initiator_tempdir) {
-           rmtree $initiator_tempdir;
-           mkdir $initiator_tempdir, 0700 or die "$initiator_tempdir: $!";
-           $i_tmp = $initiator_tempdir;
-       } else {
-           $i_tmp = tempdir();
-       }
-       my $pid = open2(\*RO, \*RI, @cmd);
-       changedir $i_tmp;
-       initiator_expect { m/^dgit-remote-push-ready/ };
-       for (;;) {
-           my ($icmd,$iargs) = initiator_expect {
-               m/^(\S+)(?: (.*))?$/;
-               ($1,$2);
-           };
-           i_method "i_resp", $icmd, $iargs;
-       }
-    };
+
+    if (defined $initiator_tempdir) {
+       rmtree $initiator_tempdir;
+       mkdir $initiator_tempdir, 0700 or die "$initiator_tempdir: $!";
+       $i_tmp = $initiator_tempdir;
+    } else {
+       $i_tmp = tempdir();
+    }
+    $i_child_pid = open2(\*RO, \*RI, @cmd);
+    changedir $i_tmp;
+    initiator_expect { m/^dgit-remote-push-ready/ };
+    for (;;) {
+       my ($icmd,$iargs) = initiator_expect {
+           m/^(\S+)(?: (.*))?$/;
+           ($1,$2);
+       };
+       i_method "i_resp", $icmd, $iargs;
+    }
+
+    my $pid = $i_child_pid;
+    $i_child_pid = undef; # prevents killing some other process with same pid
+    printdebug "waiting for remote child $pid...";
+    my $got = waitpid $pid, 0;
+    die $! unless $got == $pid;
+    die "remote child failed $?" if $?;
+
     i_cleanup();
-    die $@;
+    exit 0;
 }
 
 sub i_resp_progress ($) {