Two part question:

I'm using IPC::Open3 on Win32 to avoid the shell. Notice how double quotes are handled below. I'm assuming this is a Windows issue and not a Perl issue, correct? Extra points if you can explain the logic of this. ;)

#!/usr/bin/perl -w use strict; use IPC::Open2; my @command = ( 'perl', 'my test.pl', 'first arg1', '"second arg2"', 'word "quoted" and \"backslashed\" word', '"2word "quoted" and \"backslashed\" word"', ); my $pid = IPC::Open2::open2( \*r, \*w, @command ); print "Pid = $pid\n"; print "output:\n"; print while $_ = <r>; print "done\n";

With output on Win32 as:

Pid = 316925 output: 316925 [first arg1] 316925 [second arg2] 316925 [word] 316925 [quoted] 316925 [and] 316925 ["backslashed"] 316925 [word] 316925 [2word quoted and "backslashed" word] 316925 done done

Part two of my IPC::Open3 question:

The docs say to call waitpid($pid,0) to reap the child process -- and indeed the windows process table fills up (64 processes?) if waitpid isn't called.

See, I've got a function that returns a file handle. Under Windows it uses IPC::Open3, otherwise it does a open($fh,'-|') call. So the code that calls this function isn't suppose to know or care about how that file handle is generated.

The question is about when to call waitpid() on Windows. I assume it must be called after calling close() (or after the returned file handle goes out of scope). Is that a correct assumption?

If waitpid() has to be called after the close() that means the function that returns the file handle must store the PID some place. So, seems like I need to tie the handle.

Here's my code. I have a few follow-up questions at the end:

#!/usr/bin/perl -w use strict; my %self; my @command = ( 'perl', 'my test.pl', 'one arg', '"two arg"' ); { my $fh = windows_fork( \%self, @command ); print while <$fh>; } print "out of scope\n"; exit; sub windows_fork { my ( $self, @args ) = @_; require IPC::Open2; my ( $rdrfh, $wtrfh ); # Deal with windows quotes my @command = map { s/"/\\"/g; qq["$_"] } @args; my $pid = IPC::Open2::open2($rdrfh, $wtrfh, @command ); binmode $rdrfh, ':crlf'; tie *handle, 'call_waitpid', $rdrfh, $pid; return \*handle } package call_waitpid; use strict; sub TIEHANDLE { my ( $class, $fh, $pid ) = @_; bless { handle => $fh, pid => $pid, }, $class; } sub READLINE { my ( $self ) = @_; my $fh = $self->{handle}; return <$fh>; } sub DESTROY { my ( $self ) = @_; close $self->{handle}; waitpid $self->{pid}, 0; }

Questions:

  1. Is this how you would deal with this issue. Use a tied handle to track the PID?
  2. In READLINE I cannot do: return <$self->{handle}>; why?

    syntax error at fork.pl line 81, near "<$self->{handle"

  3. In the "windows_fork() sub I'm blessing a typeglob. The problem is it's the same typeglob for every call to windows_fork(). So if windows_fork() is called twice the handles are mixed. I tried using gensym() but couldn't get that to work. I need a way to have more than one file handle active at a time.

my $fh = windows_fork( \%self, 'perl', 'my test.pl', 'first stuff'); my $fg = windows_fork( \%self, 'perl', 'my test.pl', 'other stuff'); print while <$fh>;
Results in "other stuff" from $fh.

In reply to IPC::Open3 and Win32 by moseley

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.