rthawkcom has asked for the wisdom of the Perl Monks concerning the following question:

Trying to get SYSTEM2 module to work on Windows using Activestate Perl 5.8 or 5.10. Here is a quick test script that works on Unix, but not Windows (this is the windows version):
use System2; my ($out,$err) = system2("cmd", "/C", "dir"); print "OUT: $out ERR: $err";
There are 3 of us working on this problem and no one can figure out why it won't work. Something to do with the pseudo-threading? I've poked all around System2.pm and haven't a clue. Best I can tell is data is not coming back through the pipe. Another person thinks it has something to do with the child PID returning a negative value (which means its a pseudo-thread). 5.10 seems to crash when it opens STDERR. 5.8 will hang. Suggestions anyone?

Replies are listed 'Best First'.
Re: Using SYSTEM2 on Windows
by ikegami (Patriarch) on May 15, 2009 at 20:54 UTC
    It uses select on pipes, a unix feature. Use IPC::Run instead.
    use IPC::Run qw( run ); run( [ cmd => '/c', 'dir' ], '>', \my $out, '>', \my $err, ) or die "dir: $?" print "OUT: $out ERR: $err";
Re: Using SYSTEM2 on Windows
by Anonymous Monk on May 16, 2009 at 13:14 UTC

    I just want to point out that ActiveState's default repository doesn't have the module, and the CPAN test report lists it failing on Windows.

    I don't think there is a Windows version. Beside doing what ikegami suggests, you should examine why you were led to believe it would work on Windows -- was it specially modified or something?

      IPC-Run3 is in activestate repository. Maybe this does what you need?
      http://matrix.cpantesters.org/?dist=IPC-Run3+0.042

      #!/usr/bin/perl -w use strict; # running Active state 5.10 use IPC::Run3; run3 ("dir C:/");
      works fine.
      Sounds like you just need Run3 instead of just simply "run".

      Update:
      if you read the params to run3, you can give it handles for stdin, stdout, stderr, etc. run3 appears to be implemented on *nix as well as Windows, so I don't think you need any special Windows vs *nix code.

      Sorry for the delay. Our solution was to just rip it out entirely instead of fighting with it. I've needed a solution like this for other applications, so I took a look at the code you suggested. IPC::Run3 does seem to work, but I couldn't figure out how to connect to it. There are no examples at all and no one seems to use it. I tried setting up pipes for it, but nothing is returned when I do that:
      use IPC::Run3; use IO::Pipe; my $cmd = "cmd /D/C dir"; my $out = new IO::Pipe; $out->reader(); my $err = new IO::Pipe; $err->reader(); run3 $cmd, $out, $err; print "OUT: $out ERR: $err\n"; map {print "$_\n"}<$out>; map {print "$_\n"}<$err>;
        use IPC::Run3 qw( run3 ); my $cmd = "cmd /D/C dir"; run3 $cmd, undef, \my @out, \my @err; print "STDOUT: $_" for @out; print "STDERR: $_" for @err;

        @out and @err can be scalars if you don't need the lines to be split