3

This print 1..10 twice:

seq 10 > /tmp/ten
perl -e 'fork();seek(STDIN,0,0); print <STDIN>' </tmp/ten

I would like to do the same using IPC::Open3, but I cannot get that to work:

perl -MIPC::Open3 -e 'fork();seek(STDIN,0,0); open3(0,1,2,"cat");' < /tmp/ten
perl -MIPC::Open3 -e 'fork();seek(STDIN,0,0); open3(STDIN,STDOUT,STDERR,"cat");' < /tmp/ten
perl -MIPC::Open3 -e 'fork();seek(STDIN,0,0); open3(*STDIN,*STDOUT,*STDERR,"cat");' < /tmp/ten
perl -MIPC::Open3 -e 'fork();seek(STDIN,0,0); open3(\*STDIN,\*STDOUT,\*STDERR,"cat");' < /tmp/ten
Ole Tange
  • 31,768
  • 5
  • 86
  • 104

1 Answers1

5

First of all, the proper notation to inherit the handles is:

open3("<&STDIN", ">&STDOUT", ">&STDERR", "cat")

But printing 1..10 twice? You shouldn't rely on that happening! It will only happen if the timing is just right. In fact, it very rarely happens for me, even for your original program. The problems stem from the fact that both the parent and the child processes share the same file pointer.

Maybe to avoid having people rely on this extremely unreliable behaviour, open3 closes the first handle when it's a dup it created. It's possible to fool it as follows:

open(local *CHILD_STDIN, "<&", \*STDIN) or die $!;
open3("<&CHILD_STDIN", ">&STDOUT", ">&STDERR", "cat")

That way, open3 will close the dup CHILD_STDIN, but not STDIN itself. With this change, you will get the list printed twice when you're lucky.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • The fooling is fine, but I still cannot get it to read the file twice. – Ole Tange Feb 24 '17 at 00:41
  • 2
    Like I already explained, what you are trying to do is timing dependent, meaning it will only happen if the timing is just right. This was the case with your original program too. You're really shouldn't be doing what you are trying to do! To avoid the randomness, I replaced `fork();` with `my $pid = fork(); waitpid($pid, 0) if $fork;` when testing. That ensured that one process (the parent) only called `seek` after the other (the child) had finished reading, and thus ensured the double-printing. – ikegami Feb 24 '17 at 01:18