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

It seems that IPC::Run does not always handle STDIN/STDOUT correctly, which means that when using wperl, any calls to programs relying on STD* are failing. In particular the GraphViz module is not working. Any suggestions would be welcome. Thanks.

Replies are listed 'Best First'.
Re: IPC::Run not working with wperl
by pc88mxer (Vicar) on Mar 24, 2008 at 23:25 UTC
    This is a bit of a shot in the dark, but just try opening STDIN and STDOUT (and perhaps STDERR) to a dummy file and see what happens:
    open(STDIN, "<c:\\foo"); open(STDOUT, ">c:\\bar");
    I bet IPC::Run is expecting them to be defined, and from what I read about wperl these file handles are not initially available.

    I'd be interested to know if this works or not.

    Another option is to use the ->as_debug or ->as_canon method to get the input that will be passed to the GraphViz command (dot or whatever) and invoke the command yourself.

Re: IPC::Run not working with wperl
by xdg (Monsignor) on Mar 25, 2008 at 04:07 UTC

    I'm not sure exactly how you're using IPC::Run, but you might see if IO::CaptureOutput might do what you need. It's been tested with wperl.

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      I may try that. Is there a better alternative for GraphViz package that you know of instead though? Not thrilled about modifying that package...
Re: IPC::Run not working with wperl
by BrowserUk (Patriarch) on Mar 25, 2008 at 00:02 UTC
      Not actually using IPC::Run directly, rather using the as_jpeg() method of GraphViz package (which ends up using IPC::Run).

        The problem could be that wperl doesn't have a console. You could try prefixing the command line with cmd.exe /c ..., or even start /wait /b ....

        run ['cmd.exe', '/c', $program, $type], \$dot, ">", binary(), $out; # or run ['start', '/wait', '/b', $program, $type], \$dot, ">", binary(), $ +out;

        I don't have GraphViz to test these.

        Failing that, it would be relatively easy to replace the call to IPC::Run::run() with a call to piped open supplying the input ($dot) to the command via echo. Something along the lines of (untested):

        sub _as_generic { my($self, $type, $dot, $output) = @_; my $program = $self->{LAYOUT}; my $buffer; if ( ref $output || UNIVERSAL::isa(\$output, 'GLOB') ) { # $output is a filehandle or a scalar reference or something. # have to take a reference to a bare filehandle or run will # complain my $out = ref $output ? $output : \$output; my $pid = open my $pipe, '-|', qq[ echo $dot | $program $type +] or die $!; binmode $pipe; print $out <$pipe>; return; } elsif (defined $output) { # if it's defined it must be a filename so we'll write to it. system qq[ echo $dot | $program $type > $output ] ; return; } else { # but otherwise we capture output in a scalar my $pid = open my $pipe, '-|', qq[ echo $dot | $program $type +] or die $!; binmode $pipe; return do{ local $/; <$pipe> }; } }

        And that could be rationalised a bit.


        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.
Re: IPC::Run not working with wperl
by compiler (Initiate) on Mar 24, 2008 at 23:45 UTC
    Unfortunately open(STD*) did not yield the hoped for results. Will try using other methods as suggested. Thanks.