CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Advanced:
open2 - bidirectional pipe I/O, failed at execute local script

 



mrstupid
Novice

Jun 16, 2010, 5:31 AM

Post #1 of 2 (1453 views)
open2 - bidirectional pipe I/O, failed at execute local script Can't Post

I am planning to do the following:
read a line from a source(say STDIN);
redirect it to a script;
get output from the script and print it to screen.

I used open2() to do the bidirectional pipe I/O, and incase of blocking, I used select+sysread to do the pipe reading.

bu the subscript failed at reading from the pipe(I guess), after I put something into the pipe(the called script just echo)

please help.


following is my code:
the main script "main.pl"

Code
#!/usr/bin/perl -w 
use strict;
BEGIN {
push(@INC, ".");
}
use FileHandle;
use IPC::Open2;


my %test_h = ();

sub test {
my $in;
my $out;
#my $pid = open2($in, $out, "cat " );
my $pwd = `pwd`;
chomp($pwd);
my $pid = open2($test_h{"in"}, $test_h{"out"}, "./XXX.pl" );
printf STDOUT ("%x %d %x %d\n", $test_h{"in"}, fileno($test_h{"in"}), $test_h{"out"}, fileno($test_h{"out"}));
while(1) {
my $out = $test_h{"out"};
printf $out ("%s", "stuff\n"); #PUT STRINGS INTO THE PIPE.
printf $out ("stuff\n");

my $in = $test_h{"in"};
#my $got = <$in>;
#my $got = <{$test_h{"in"}}>;
#printf STDOUT ("WE GET: %s\n", $got);
my ($eof, @lines) = &nonblockGetLines($in); #Now try non-block read from the pipe.
if($eof) { last; }
foreach my $line (@lines) {
printf STDOUT ("GOT: %s\n", $line);
}
sleep(1);
}
}

# Returns: ($eof,@lines)
my %nonblockGetLines_last;
sub nonblockGetLines {
my $fh = $_[0];
my $rfd = '';
$nonblockGetLines_last{$fh} = ''
unless defined $nonblockGetLines_last{$fh};

#set file handle bit mask
vec($rfd, fileno($fh), 1) = 1;
#if something's coming
my $out_fd = 0;
if (not select($out_fd=$rfd, undef, undef, 0)>=0 )
{
printf STDERR ("%x select not ready.\n", $fh);
return (0);
}
printf STDERR ("OUT_FD:%x IN_FD:%x fileno: %d \n", ord($out_fd), ord($rfd), fileno($fh));

################################################
#the $out_fd is 0, this means no data source is ready? but it should echo something since I have put something into the pipe.
################################################
if(not vec($out_fd, fileno($fh), 1)) {

printf STDERR ("%x not this one.\n", $fh);
return (0);
}
my $buf = '';
my $n = sysread($fh, $buf, 1024*1024, 0);
if ( ! defined $n ) {
#on error, we just print an error message
printf STDERR ("MAPPER: %x got a read error at input line.\n", $fh);
}elsif($n == 0) {
# If we're done, make sure to send the last unfinished line
return (1,$nonblockGetLines_last{$fh});
}
# Prepend the last unfinished line
$buf = $nonblockGetLines_last{$fh}.$buf;
# And save any newly unfinished lines
if(substr($buf,-1) !~ /[\r\n]/ && $buf =~ s/([^\r\n]*)$//) {
$nonblockGetLines_last{$fh} = $1;
} else {
$nonblockGetLines_last{$fh} = '';
}
return $buf ? (0,split(/\n/,$buf)) : (0);
}

&test();


the called script "XXX.pl", for test it just echo :

Code
 #!/usr/bin/perl -w 
#


while(<STDIN>) {
print "M2\t", $_;
}



(This post was edited by mrstupid on Jun 16, 2010, 6:08 AM)


mrstupid
Novice

Jun 16, 2010, 5:57 AM

Post #2 of 2 (1449 views)
Re: [mrstupid] bidirectional pipe I/O, failed at execute local script [In reply to] Can't Post

I have tried to replace this line:
my $pid = open2($test_h{"in"}, $test_h{"out"}, "./XXX.pl" );

with:

my $pid = open2($test_h{"in"}, $test_h{"out"}, "cat" );
and the program works FINE.
so I think there might be some problem at calling the local script.

I have also tried change ""./XXX.pl" to "perl ./XXX.pl" or "XXX.pl", all didn't work.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives