Passing data from child to parent after exec in Perl

ipc, perl

Solution

This might be helpful:

#!/usr/bin/perl
open (my $child, "-|","./child.pl") or die("$!");
while (<$child>) {
  print "P: $_";
}
close($child);

open function, from perldoc:

For three or more arguments if MODE is |- , the filename is interpreted as a command to which output is to be piped, and if MODE is -| , the filename is interpreted as a command that pipes output to us.

If you don't want to touch the stdout then you need cooperation from the child and then you can use named pipes:

parent.pl

#!/usr/bin/perl
use strict;
use warnings;
use Fcntl;
use POSIX;
my $fpath = '.named.pipe';

mkfifo($fpath, 0666) or die "mknod $!";
system("perl child.pl &");
sysopen(my $fifo, $fpath, O_RDONLY) or die "sysopen: $!";

while (<$fifo>) {
  print "P: $_";
}
close($fifo);
unlink($fifo);

child.pl

#!/usr/bin/perl
use strict;
use warnings;
use Fcntl;
use POSIX;

my $fpath = '.named.pipe';
sysopen(my $fifo, $fpath, O_WRONLY) or die "sysopen: $!";
print "screen hello\n";
print $fifo "parent hello\n";
close($fifo);

Problem

I would like to call a perl program `child.pl` in another perl program `parent.pl`, and hope to pass data from `child.pl` to `parent.pl` and print these data by `parent.pl`. `system("perl child.pl")` may not work, since parent.pl would will do nothing until `child.pl` completes. I read the online doc of perlipc, it seems `pipe()` and `fork()` could match some of my needs, but I failed to find a method to pass data from child process to parent after `exec`. Here's the code of `parent.pl`: ``` #!/usr/bin/perl -w pipe(FROM_CHILD, TO_PARENT); $pid = fork(); if ($pid == 0) { # We're in the child process. close(FROM_CHILD); # Send data to parent. print TO_PARENT "Hello, parent\n"; # I can pass data to parent before exec exec("perl child.pl"); # But how what should I do after exec, in child.pl? exit(0); # Terminate child. } elsif (undef $pid) { print "Not defined: means an error."; } else { # Parent process. close(TO_PARENT); $data = <FROM_CHILD>; print "From child: $data\n"; $id = wait(); print "Child $id is dead.\n"; ```

Original source