A third way is to call pipe before fork to set up a reader and writer handle. You'll want to set the writer to autoflush, and to close the unwanted end of the pipe in each process.
That is low level, so is very flexible and powerful. Writing C in Perl is not always a bad thing.
Here's how to set up the child as a coprocess, taking STDIN from the parent, and writing back STDOUT to the parent. That needs two pipes, one each direction.
my ($reader,$writer,$cpid);
{
pipe $reader, local *STDOUT or die $!;
pipe local(*STDIN), $writer or die $!;
$cpid = fork;
defined $cpid or die $!;
last if $cpid;
# child
close $reader or die $!;
close $writer or die $!;
$| = 1;
exec '/path/to/foo', @foo_args;
die 'Failed to launch foo: ', $!;
}
# parent
select((select($writer), $| = 1)[0]); # see 'perldoc -f select'
# builtin 4-arg select or IO::Select may be handy here
# . . .
waitpid $cpid;
Untested. Will fail if foo is naive about file descriptors for STDIN and STDOUT.
|