summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xvest/line_mediator.pl58
1 files changed, 36 insertions, 22 deletions
diff --git a/vest/line_mediator.pl b/vest/line_mediator.pl
index 2b8fa77c..37dea7d6 100755
--- a/vest/line_mediator.pl
+++ b/vest/line_mediator.pl
@@ -25,7 +25,8 @@ if (scalar @ARGV) {
pop @c1;
my @c2=@ARGV;
@ARGV=();
-(scalar @c1 && scalar @c2) || die "usage: $0 cmd1 args -- cmd2 args; hooks up two processes, 2nd of which has one line of output per line of input, expected by the first, which starts off the communication. crosses stdin/stderr of cmd1 and cmd2 line by line (both must flush on newline and output. cmd1 initiates the conversation (sends the first line). DEBUG=1 env var enables debugging output. default: attempts to cross stdin/stdout of c1 and c2 directly (via two unidirectional posix pipes created before fork). env SERIAL=1: (no parallelism possible) but lines exchanged are logged if DEBUG. if SNAKE then stdin -> c1 -> c2 -> c1 -> stdout";
+(scalar @c1 && scalar @c2) || die qq{usage: $0 cmd1 args -- cmd2 args; all options are environment variables. CROSS=1 hooks up two processes, 2nd of which has one line of output per line of input, expected by the first, which starts off the communication. crosses stdin/stderr of cmd1 and cmd2 line by line (both must flush on newline and output. cmd1 initiates the conversation (sends the first line). DEBUG=1 env var enables debugging output. default: attempts to cross stdin/stdout of c1 and c2 directly (via two unidirectional posix pipes created before fork). env SERIAL=1: (no parallelism possible) but lines exchanged are logged if DEBUG. if SNAKE then stdin -> c1 -> c2 -> c1 -> stdout. if PIPE then stdin -> c1 -> c2 -> stdout (same as shell c1|c2, but with SERIAL you can see the intermediate in real time; you could do similar with c1 | tee /dev/fd/2 |c2. DIRECT=1 (default) will override SERIAL=1. CROSS=1 (default) will override SNAKE or PIPE.
+};
info("1 cmd:",@c1,"\n");
info("2 cmd:",@c2,"\n");
@@ -36,14 +37,31 @@ sub lineto {
shift;
print @_;
}
-my $snake=$ENV{SNAKE};
-my $serial=$ENV{SERIAL};
-if ($serial || $snake) {
+my $mode='CROSS';
+my $ser='DIRECT';
+$mode='PIPE' if $ENV{PIPE};
+$mode='SNAKE' if $ENV{SNAKE};
+$mode='CROSS' if $ENV{CROSS};
+$ser='SERIAL' if $ENV{SERIAL};
+$ser='DIRECT' if $ENV{DIRECT};
+$ser='SERIAL' if $mode eq 'SNAKE';
+info("mode: $mode\n");
+info("connection: $ser\n");
+
+if ($ser eq 'SERIAL') {
my ($R1,$W1,$R2,$W2);
my $c1p=open2($R1,$W1,@c1); # Open2 R W backward from Open3.
my $c2p=open2($R2,$W2,@c2);
- if ($snake) {
- info("SNAKE mode\n");
+ if ($mode eq 'CROSS') {
+ while(<$R1>) {
+ info("1:",$_);
+ lineto($W2,$_);
+ last unless defined ($_=<$R2>);
+ info("1|2:",$_);
+ lineto($W1,$_);
+ }
+ } else {
+ my $snake=$mode eq 'SNAKE';
while(<STDIN>) {
info("IN:",$_);
lineto($W1,$_);
@@ -52,20 +70,13 @@ if ($serial || $snake) {
lineto($W2,$_);
last unless defined ($_=<$R2>);
info("IN|1|2:",$_);
- lineto($W1,$_);
- last unless defined ($_=<$R1>);
- info("IN|1|2|1:",$_);
+ if ($snake) {
+ lineto($W1,$_);
+ last unless defined ($_=<$R1>);
+ info("IN|1|2|1:",$_);
+ }
lineto(*STDOUT,$_);
}
- } else {
- info("SERIAL mode\n");
- while(<$R1>) {
- info("1:",$_);
- lineto($W2,$_);
- last unless defined ($_=<$R2>);
- info("2:",$_);
- lineto($W1,$_);
- }
}
} else {
info("DIRECT mode\n");
@@ -76,14 +87,17 @@ if ($serial || $snake) {
while (not defined ($pid=fork())) {
sleep 1;
}
- POSIX::close(STDOUT_FILENO);
- POSIX::close(STDIN_FILENO);
+ my $pipe = $mode eq 'PIPE';
+ unless ($pipe) {
+ POSIX::close(STDOUT_FILENO);
+ POSIX::close(STDIN_FILENO);
+ }
if ($pid) {
POSIX::dup2($rw1[1],STDOUT_FILENO);
- POSIX::dup2($rw2[0],STDIN_FILENO);
+ POSIX::dup2($rw2[0],STDIN_FILENO) unless $pipe;
exec @c1;
} else {
- POSIX::dup2($rw2[1],STDOUT_FILENO);
+ POSIX::dup2($rw2[1],STDOUT_FILENO) unless $pipe;
POSIX::dup2($rw1[0],STDIN_FILENO);
exec @c2;
}