summaryrefslogtreecommitdiff
path: root/FugueConfig.pm
diff options
context:
space:
mode:
Diffstat (limited to 'FugueConfig.pm')
-rw-r--r--FugueConfig.pm123
1 files changed, 69 insertions, 54 deletions
diff --git a/FugueConfig.pm b/FugueConfig.pm
index b0e9b72..ef69e9d 100644
--- a/FugueConfig.pm
+++ b/FugueConfig.pm
@@ -1,6 +1,7 @@
package FugueConfig;
use Sys::Hostname;
+use IO::Handle;
use strict;
my $rsh = $ENV{"RSH"};
@@ -48,32 +49,34 @@ sub parse {
# empty lines
if (/^\s*$/) {
next;
+
# comments
} elsif (/^\s*\#.*$/) {
push(@data, ['comment', $_]);
+
} else {
- my ($type, $host, $name, $command, @param) =
+ my ($type, $host, $name, $command, $param) =
m/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)\#*.*$/ ;
- #print "t=$type h=$host n=$name c=$command p=".join(' ', @param)."\n";
+ #print "### t=$type h=$host n=$name c=$command p=$param\n";
+
if (not defined $type) {
- warn ("*** FugueConfig::parse WARNING : ".
- "syntax error at line $line : \n\t=> $_\n");
+ warn ("[FugueConfig][WARNING][line $line] syntax error : ".
+ "\n\t=> $_\n");
next;
}
unless ($type eq 'global' or $type eq 'local' or
$type eq 'begin' or $type eq 'end') {
- warn ("*** FugueConfig::parse WARNING : ".
- "unknown command type '$type' at line $line. Ignored.\n");
+ warn ("[FugueConfig][WARNING][line $line] unknown command type ".
+ "'$type'\n");
next;
}
if ($appname{$name}) {
- warn ("*** FugueConfig::parse WARNING : ".
- "at line $line at least 2 agents have the same name '$name'; ".
- "skipping all but the first\n");
+ warn ("[FugueConfig][WARNING][line $line] at least 2 agents have ".
+ "the same name '$name'; skipping all but the first\n");
next;
}
$appname{$name} = 1 if $type eq 'global' or $type eq 'local';
- push(@data, [$type, $host, $name, $command, [@param]]);
+ push(@data, [$type, $host, $name, $command, $param]);
}
}
@@ -88,64 +91,76 @@ sub parse {
sub launchAgent {
my ($appname, $host, $command, $options, $bus) = @_;
- my @options = @$options if ref($options) eq 'ARRAY';
- push(@options, -b => $bus) if $bus;
- my $command_opt = $command.' '.join(' ', @options);
- my $pid = fork;
- warn ("*** FugueConfig::launchAgent WARNING: Could not fork!\n"), return
- unless defined $pid;
-
- if ($pid) {
- # parent
- print "*** FugueConfig::launchAgent INFO: $host: launching $appname agent ".
- "with \'$command_opt\' (pid=$pid)\n";
- return ($pid);
- } else {
- # child
- my $awk_command = "awk -W interactive '{print \"$appname  \", \$0;}'";
- if ($host eq 'localhost' or $host eq hostname() ) {
- exec "$command_opt 2>&1 | $awk_command" or
- warn "*** FugueConfig::launchAgent WARNING: Error executing $command\n";
- } else {
- exec "$rsh -n $host '$command_opt' 2>&1 | $awk_command "
- or warn "*** FugueConfig::launchAgent WARNING: Error executing ".
- "$command on $host\n";
- }
- }
-
+ $options .= " -b $bus" if $bus;
+ my $command_opt = $command;
+ $command_opt .= ' '.$options unless $options =~ /^\s*$/;
+ &_launch($appname, $host, $command_opt, 'agent');
+
} # end launchAgent
+
# launch a given command (not an ivy agent) on a given host
sub launchCommand {
my ($type, $host, $command, $options) = @_;
- my @options = @$options if ref($options) eq 'ARRAY';
- my $command_opt = $command.' '.join(' ', @options);
+ my $command_opt = $command;
+ $command_opt .= ' '.$options unless $options =~ /^\s*$/;
+ &_launch($type, $host, $command_opt, 'command');
+
+} # end launchCommand
+
+
+
+sub _launch {
+
+ my ($label, $host, $command_opt, $type) = @_;
my $pid = fork;
- warn ("*** FugueConfig::launchCommand WARNING: Could not fork!\n"), return
+ warn ("[FugueConfig][WARNING] Could not fork $type \'$command_opt\'!\n"), return
unless defined $pid;
-
+
+ # parent P1
if ($pid) {
- # parent
- print "*** FugueConfig::launchCommand INFO: $host: launching command ".
- "\'$command_opt\' (pid=$pid)\n";
+ print "[FugueConfig][INFO] launch on $host $label $type \'$command_opt\' ".
+ "(pid=$pid)\n";
return ($pid);
+
+ # child P2
} else {
- # child
- my $awk_command = "awk -W interactive '{print \"$type  \", \$0;}'";
- if ($host eq 'localhost' or $host eq hostname() ) {
- exec "$command_opt 2>&1 | $awk_command" or
- warn "*** FugueConfig::launchCommand WARNING: Error executing ".
- "$command\n";
+
+ # overload parent trap
+ $SIG{INT} = 'DEFAULT';
+
+ # remote command
+ $command_opt = "$rsh -n $host '$command_opt'"
+ unless $host eq 'localhost' or $host eq hostname();
+
+ pipe(READER, WRITER);
+ WRITER->autoflush(1);
+ my $pid2 = fork;
+ warn ("[FugueConfig][WARNING] Could not fork $type \'$command_opt\'!\n"),
+ return
+ unless defined $pid2;
+ # parent P2
+ if ($pid2) {
+ close READER;
+ CORE::open(STDOUT, ">&=WRITER") or
+ die "[FugueConfig][WARNING] Couldn't redirect STDOUT";
+ exec "$command_opt" or
+ die "[FugueConfig][WARNING] Couldn't launch $command_opt";
+ # child P3
} else {
- exec "$rsh -n $host '$command_opt' 2>&1 | $awk_command "
- or warn "*** FugueConfig::launchCommand WARNING: Error executing ".
- "$command on $host\n";
+ close WRITER;
+ while(<READER>) {
+ chomp();
+ print "$label $_\n";
+ }
+ close READER;
+ exit;
}
- }
-
-} # end launchCommand
+ }
+
+} # end _launch
1;