http://www.perlmonks.org?node_id=674146


in reply to Re: bidirectional challange
in thread bidirectional challange

Based on CB chat, there's some confusion with my solution, so I'll elaborate.

It's my understanding that you want to do something along the lines of

while (<STDIN> or <TNIN>) { if (we_read_from_STDIN()) { print TNOUT do_this($_); } else { print STDOUT do_that($_); } }

Of course, that's not valid Perl. That where IO::Select comes in.

use IO::Select qw( ); my $sel = IO::Select->new(\*STDIN, \*TNIN); MAIN_LOOP: while (my @ready = $sel->can_read()) { for my $fh (@ready) { my $bytes_read = sysread($fh, my $data='', 4096) or last MAIN_LOOP; if ($fh == \*STDIN) { print TNOUT do_this($data); } else { print STDOUT do_that($data); } } }

We can't use <$fh> since that would block when only part of a line has arrived. If you want to do line-based IO, you'll have to do your own line building:

use IO::Select qw( ); my $sel = IO::Select->new(\*STDIN, \*TNIN); my %bufs; MAIN_LOOP: while (my @ready = $sel->can_read()) { for my $fh (@ready) { our $buf; local *buf = \$bufs{$fh}; # Alias my $bytes_read = sysread($fh, $buf, 4096, length($buf)) or last MAIN_LOOP; my $line_end = index($buf, $/); next if $line_end < 0; my $line = substr($buf, 0, $line_end+1, ''); if ($fh == \*STDIN) { print TNOUT do_this($line); } else { print STDOUT do_that($line); } } }

Update: