aboutsummaryrefslogtreecommitdiff
path: root/scripts/SSH.pm
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-12-05 17:50:29 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-12-05 17:50:29 +0000
commit365f3028ddfb5487f35ebbb9adc42ddf9459113d (patch)
tree211e4ba436ffa2f2badb458386864968837e3aff /scripts/SSH.pm
parentf42a505ab71ba421797ac511e1221ccbefef8ab9 (diff)
* Use CamelCase for the Perl modules.
Diffstat (limited to 'scripts/SSH.pm')
-rw-r--r--scripts/SSH.pm50
1 files changed, 50 insertions, 0 deletions
diff --git a/scripts/SSH.pm b/scripts/SSH.pm
new file mode 100644
index 000000000..44a0e6f31
--- /dev/null
+++ b/scripts/SSH.pm
@@ -0,0 +1,50 @@
+use strict;
+use File::Temp qw(tempdir);
+
+our @sshOpts = split ' ', ($ENV{"NIX_SSHOPTS"} or "");
+
+my $sshStarted = 0;
+my $sshHost;
+
+# Open a master SSH connection to `host', unless there already is a
+# running master connection (as determined by `-O check').
+sub openSSHConnection {
+ my ($host) = @_;
+ die if $sshStarted;
+ $sshHost = $host;
+ return 1 if system("ssh $sshHost @sshOpts -O check 2> /dev/null") == 0;
+
+ my $tmpDir = tempdir("nix-ssh.XXXXXX", CLEANUP => 1, TMPDIR => 1)
+ or die "cannot create a temporary directory";
+
+ push @sshOpts, "-S", "$tmpDir/control";
+
+ # Start the master. We can't use the `-f' flag (fork into
+ # background after establishing the connection) because then the
+ # child continues to run if we are killed. So instead make SSH
+ # print "started" when it has established the connection, and wait
+ # until we see that.
+ open SSH, "ssh $sshHost @sshOpts -M -N -o LocalCommand='echo started' -o PermitLocalCommand=yes |" or die;
+
+ while (<SSH>) {
+ chomp;
+ if ($_ eq "started") {
+ $sshStarted = 1;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+# Tell the master SSH client to exit.
+sub closeSSHConnection {
+ if ($sshStarted) {
+ system("ssh $sshHost @sshOpts -O exit 2> /dev/null") == 0
+ or warn "unable to stop SSH master: $?";
+ }
+}
+
+END { my $saved = $?; closeSSHConnection; $? = $saved; }
+
+return 1;