
mrstupid
Novice
Jun 16, 2010, 5:31 AM
Post #1 of 2
(791 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"
#!/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 :
#!/usr/bin/perl -w # while(<STDIN>) { print "M2\t", $_; }
(This post was edited by mrstupid on Jun 16, 2010, 6:08 AM)
|