The program I am referring to is the second program shown in this section here. A small modification of it is:
#!/usr/bin/perl -w
use IPC::Open2;
use Symbol;
$WTR = gensym(); # get a reference to a typeglob
$RDR = gensym(); # and another one
$pid = open2($RDR, $WTR, 'bc');
print "$pid\n";
while (<STDIN>) { # read commands from user
print $WTR $_; # write a command to bc(1)
$line = <$RDR>; # read the output of bc(1)
print STDOUT "$line"; # send the output to the user
}
This program runs ok. Say its name is prop_7_2_39_2.pl, so a typical interaction with it is:
>./prop_7_2_39_2.pl
75955
2+2
4
quit
>
That is, after typing "quit", child process bc
becomes defunct, and after that I need to feed a newline to actually finish the perl parent. Why the <STDIN>
is evaluated to false? I understand that perl evaluates definition of <STDIN>
. The somewhat related program
#!/usr/bin/perl -w
while(<STDIN>){}
does not end.
After sending quit
to bc
it terminates which closes the reading end of the pipe. Your next print $WTR $_
will then fail and generate the SIGPIPE
signal that terminates the program - unless you install a signal handler for it.
An alternative solution could be to check that reading from bc
after you've sent something to it succeeds:
while (<STDIN>) { # read commands from user
print $WTR $_; # write a command to bc(1)
my $line = <$RDR>; # read the output of bc(1)
if($line) {
print STDOUT "$line"; # send the output to the user
} else {
last; # break out of the while loop
}
}
print "Controlled ending...\n";