You do need to use select, or at least I can't think of any other way to do this.
Your use of sysread is fine; the 4096 is just a maximum. You can see how much data was actually read by looking at length($answer), and if there's more than 4096 bytes available you'd have to call this in a loop.
The reason for your problem is because you're not using IO::Select quite right. You're passing a timeout of 0 to can_read, which asks it to return immediately if there is no data ready yet. What I think you want to do is create one IO::Select object with both handles, then ask it to wait until one or both have something ready to read. Something like this:
#!/usr/bin/perl use warnings; use strict; use IPC::Open3; use IO::Select; #interface to "bc" calculator my $pid = open3(\*WRITE, \*READ,\*ERROR,"bc"); my $sel = new IO::Select(); $sel->add(\*READ); $sel->add(\*ERROR); my($error,$answer)=('',''); while(1){ print "Enter expression for bc, i.e. 2 + 2\n"; chomp(my $query = <STDIN>); #send query to bc print WRITE "$query\n"; foreach my $h ($sel->can_read) { my $buf = ''; if ($h eq \*ERROR) { sysread(ERROR,$buf,4096); if($buf){print "ERROR-> $buf\n"} } else { sysread(READ,$buf,4096); if($buf){print "$query = $buf\n"} } } }
This technique won't work if bc might output more than one line. One way to work around that is to fork a process to handle the reading from bc, and use the parent process to handle writing. There's an example of this in Re: Perl Web Zombie problem.
In reply to Re: IPC::Open3 and blocking filehandles
by sgifford
in thread IPC::Open3 and blocking filehandles
by zentara
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |