in reply to Open3 and IO:Select on Win32

Win32 pipes do not support select, thus using open3 that way on win32 doesn't work.

As an alternative, consider Win32::SocketPair::winopen2_5().


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: Open3 and IO:Select on Win32
by Elegant (Novice) on Sep 12, 2014 at 07:00 UTC

    Alright, I'll look into it. Documentation is a bit rough (new to Perl) but I should be able to figure this out...

      Documentation is a bit rough

      I've annotated a short test script that was kicking around in my test directory. Maybe it'll clarify things a little?

      #! perl -slw use strict; use Win32::Socketpair qw[ winopen2_5 ]; ## Open a pipe to perl.exe -c ## Retrieving the pid and the socket handle my( $pid, $sock ) = winopen2_5( 'perl.exe', '-c' ); ## Print a short script to it for syntax checking print $sock <<'EOP'; my $x = 365.25**3; my $y = qx[ perl -c -e"say 'boo'"; ]; my $z = sub { print $sock <<; my $x = 365.25**3; my $y = qx[ perl -c -e"say 'boo'"; ]; my $z = sub { print $sock <<; my $x = 365.25**3; my $y = qx[ perl -c -e"say 'boo'"; ]; my $z = sub { 1; }; }; }; EOP ## Tell the socket that we have finsihed writing to it ## Has the effect of allowing the pelr process to know ## that no more data is coming, so it can process the script shutdown $sock, 1; ## Read back all the output from the perl process ## -- stdout & stderr -- and display on terminal print while <$sock>; ## Close the socket close $sock; ## Start another copy of perl with a one liner argument ## that outputs to both stdout and stderr ( $pid, $sock ) = winopen2_5( 'perl.exe', q[-E"say 'hello'; warn; die; +"] ); ## Tell the socket we've finished writing shutdown $sock, 1; ## print teh retrieved output to the terminal print while <$sock>; ## and done close $sock; ## The output produced is below __END__ C:\test>winopen2_5 - syntax OK Warning: something's wrong at -e line 1. Died at -e line 1. hello

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Now that's quite a bit different and seems to make more sense. I am now able to get the output I desire but there appears to be some random characters that are printed with the first line. I assume that it'll wait for the process to complete before the shutdown call is made? Or is waitpid needed?

        Also, I was checking $fh against $out and $err before (see OP), I don't really seem to have that option now. What can I do to compensate or should I not bother?

        sub sys { my $self = shift; my $app = shift; more(); TRACE "sys > $app @_"; my($pid, $sock) = Win32::Socketpair::winopen2_5($app, @_) or LOGDIE "f +ailed to open $app: @_"; shutdown $sock, 1; my ($sel, $buf); $sel = new IO::Select($sock); SYSLOOP: while(my @ready = $sel->can_read) { foreach my $fh (@ready) { my $line = <$fh>; if(not defined $line) { $sel->remove($fh); next; } $buf .= $line; } } waitpid($pid, 0); close $sock; less(); return $buf; }