diff options
-rwxr-xr-x | vest/line_mediator.pl | 58 |
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; } |