1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#!/usr/bin/env perl
eval 'echo "Called with something not perl"' && exit 1 # Non-Perl protection.
if 0;
use strict;
use warnings;
use 5.12.1;
# FILENAME: ssh_multiplex.pl
# CREATED: 02/08/11 12:18:23 by Kent Fredric (kentnl) <kentfredric@gmail.com>
# ABSTRACT: Spawn Background SSH Masters for Gentoo Git Sources
use File::Which qw( which );
use Data::Dump qw( dump );
my $ssh_cmd = which(qw( ssh ));
my %flag_map = (
background => ['-f'],
no_execute_command => ['-N'],
no_stdin => ['-n'],
control_master => [ '-o', 'ControlMaster=auto' ],
);
my @pids;
spawn_cmd(
{
pids => \@pids,
params => [qw( background no_execute_command no_stdin control_master )],
connect => 'git@github.com',
cleanup => sub {
say "\e[31mConnected to git\@github.com\e[0m";
},
}
);
spawn_cmd(
{
pids => \@pids,
params => [qw( background no_execute_command no_stdin control_master )],
connect => 'git@git.overlays.gentoo.org',
cleanup => sub {
say "\e[32mConnected to git\@git.overlays.gentoo.org\e[0m";
},
}
);
for (@pids) {
waitpid $_, 0;
}
say "Done.";
exit;
sub map_option {
my ($option) = @_;
if ( not exists $flag_map{$option} ) {
require Carp;
Carp::croak("Map for $option undefined");
}
return @{ $flag_map{$option} };
}
sub map_literal_array {
my ($literal) = @_;
return @{$literal};
}
sub map_param {
my ($param) = @_;
return map_option($param) if not ref $param;
return map_literal_array($param) if ref $param eq 'ARRAY';
require Carp;
Carp::croak("Unhandled parameter $param");
}
sub spawn_child {
my (@cmd) = @_;
local $!;
local $?;
local $@;
my $cleanup = pop @cmd;
my $pid;
if ( not defined( $pid = fork() ) ) {
my (%error) = ( '$!', $!, '$?', $?, '$@', $@ );
require Carp;
Carp::croak( 'Forking Failed :( ' . dump \%error );
}
if ($pid) {
return $pid;
}
local $!;
local $?;
local $@;
system(@cmd) == 0 or do {
my (%error) = ( '$!', $!, '$?', $?, '$@', $@ );
require Carp;
Carp::croak( 'Running command Failed :( ' . dump \%error );
};
$cleanup->();
exit;
}
sub spawn_cmd {
my ($args) = @_;
my @outargs = map { map_param($_) } @{ $args->{'params'} };
my (@cmd) = ( $ssh_cmd, @outargs, $args->{'connect'} );
say "Spawning " . dump( \@cmd );
$args->{cleanup} //= sub {
say "\e[31mConnected to " . $args->{'connect'} . "\e[0m";
};
push @{ $args->{pids} }, grep { defined } spawn_child( @cmd, $args->{cleanup} );
}
|