Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

IPC::Open3 STDIN never sees eof on win32?

by Yary (Pilgrim)
on Dec 05, 2012 at 04:15 UTC ( #1007191=perlquestion: print w/replies, xml ) Need Help??
Yary has asked for the wisdom of the Perl Monks concerning the following question:

Howdy monks,

I've seen more than a few questions about the stdout/stderr handles with IPC::Open3, but not yet found people with the issue I'm having on stdin. Here's a one-liner that prints "Hello" on Unix, but hangs on Win32.

perl -MIPC::Open3 -e "open3(\*IN,'>&STDOUT','>&STDERR',qw[perl -pe 1]) +;print IN 'Hello';close IN;wait"
It is about as simplified as I can get it. There's a subprocess which just prints everything it reads from STDIN, that's the perl -pe 1. Around it is wrapped a call to open3, and the caller prints in a string, closes IN, which should generate an EOF for the child... but it never happens.

I have tried printing a multi-line string, reading just one line with "readline" or "scalar <>" does work, showing that open3 is indeed communicating over IN. The child sees input written by the parent, it does not see the parent closing IN when running under Win32.

I am about to go to bed, and in the morning will just use open("|cmd") with some fancy redirects to get stdout and stderr where I want to go... unless a genius can point out what I'm doing wrong/a solution... preferably using only standard modules (or those that ship with ActiveState's distribution)

thanks, and sorry for brain cells lost, in advance

Replies are listed 'Best First'.
Re: IPC::Open3 STDIN never sees eof on win32?
by Anonymous Monk on Dec 05, 2012 at 08:45 UTC
      I forgot to explain that "works" but leaves zombies which you can kill after sleep-ing for a while or a few iterations of  waitpid $kpid, WNOHANG;
        Alas this doesn't fix the core problem of the subprocess hanging in the read loop. I'll modify the example a bit to make the misbehavior clearer, incorporating some of your suggestions & some from other nodes:
        perl -MIPC::Open3 -MPOSIX=WNOHANG -e "open CPYOUT,'>&STDOUT';open CPYE +RR,'>&STDERR';$pid=open3(\*IN,'>&CPYOUT','>&CPYERR','perl','-pe','END + {warn qq(Finished\n)}');close CPYOUT;close CPYERR;print IN 'Hello',$ +/;close IN;sleep 3;waitpid $pid,WNOHANG"
        The one liner is getting long with it's new features:

        The subprocess has an END block printing that it is done. In "real life" the sub-process reads all the input, then prints a bunch of output when it is done reading all the input. The purpose of this question is figuring out how get the subprocess to move beyond its read loop.

        The parent is closing its copies of the output handles as suggested in another thread. We do see output on the screen, and the parent eventually exits anyway, so the child is not blocking on output.

        Also added a waitpid, which doesn't reap, and I end up with a zombie process. Only it isn't truly a zombie, it is still waiting on stdin, active and parentless. Which explains why wait/waitpid "hang"- the child hasn't exited.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1007191]
Approved by mbethke
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2018-05-21 05:43 GMT
Find Nodes?
    Voting Booth?