Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

waitpid on Win32 ... wait forever

by syphilis (Archbishop)
on May 08, 2009 at 07:03 UTC ( [id://762762]=perlquestion: print w/replies, xml ) Need Help??

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

Hi,
On Linux and Cygwin, the below demo runs to completion immediately - which is as I expect. But on Win32 (perl-5.10.0), it hangs forever at waitpid $pid, 0;

What's the way to have this working correctly on Win32 ? The waitpid documentation states that "waiting for a particular pid with FLAGS of 0 is implemented everywhere".
use warnings; use strict; use Symbol qw(gensym); use IPC::Open3; my $out = gensym(); my $err = gensym(); my $cmd = 'cd'; my $pid = open3(undef, $out, $err, $cmd); waitpid $pid, 0;
The Net::SSLeay test file t/local/00_ptr_cast.t contains code very much like that (except that $cmd contains something useful) - needless to say, Ctrl-C is the only way to terminate that test script on Win32.

Cheers,
Rob

Replies are listed 'Best First'.
Re: waitpid on Win32 ... wait forever
by BrowserUk (Patriarch) on May 08, 2009 at 08:50 UTC

    If you service the pipes, the process will terminate:

    use warnings; use strict; use Symbol qw(gensym); use IPC::Open3; my $out = gensym(); my $err = gensym(); my $cmd = 'dir'; my $pid = open3(undef, $out, $err, $cmd); 1 while <$out>; 1 while <$err>; waitpid $pid, 0;

    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.
      If you service the pipes, the process will terminate

      Yes, that stops it from hanging, but when I apply that change to 00_ptr_cast.t the executable that should be built by $cmd doesn't get built. The object file gets created, but that's as far as it gets.

      This stuff is unbelievably buggy. Stuff that works in a demo script fails when applied to the 00_ptr_cast test script. And it's a bloody pain - I have to close the console and open up a new one so I can delete the test executable (on those occasions where the test executable actually gets built).

      Cheers,
      Rob
        ... the executable that should be built by $cmd doesn't get built.

        Well, one problem (assuming that you're using MS VC for these builds), is that -o is not a valid switch for cl. It would have to be /Fe to name the executable; or /Fo to name the object file. (It's unclear to me which -o is trying to do).

        Also, the script doesn't add an extension to $output, so if it is the object file, the linker probably won't find it. If it is the executable, it won't work.

        Which brings us to the question: Why are they suppressing and ignoring all the output from the commands? The very stuff which would tell you what is going wrong. The answer is of course--because it would mess with the totally useless bean-counting output from the test harness!

        This stuff is unbelievably buggy.

        Without having looked at the rest of what's going on, just the two .t files you've linked, I do not understand at all why they are using IPC::Open3 (which historically I've had no end of trouble with on windows anyway), rather than a simple system command?

        All they seem to be doing is running a command and waiting for it to finish. The only benefit of using open3 seems to be the ability to ignore the output from the commands stdout & stderr so they do not interfere with the test harness' use of stdout & stderr (which I've said enough on previously and which falls on deaf ears!).

        Personally, I'd try replacing all the uses of open3() with system $cmd 2>&1 >nul, which I believe would achieve the same thing and avoid the problems of open3 entirely.

        Under 32-bit, I always installed Net::SSLeay via PPM (from trouchelle.com or maybe one of jenda's repositories?)...so someone must have solved these problems under win32. I find it hard to believe that they are seriously more severe under win64?

        I could be wrong on that--I'm still only just starting out on win64--there is a lot to discover--but mostly so far, most things seem to work much the same.

        Suggestion: Service the output using:

        my $pid = open3 ....; print "# $_" while <$out>; print "# $_" while <$err>; waitpid $pid, 0;

        By commentifying the compiler output it should get passed through by the test harness and allow you to see the diagnostics that will tell you what is going on. Maybe?


        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.
      Not sufficient. That won't help if the child blocks on printing STDERR, since the parent is blocked reading from the child's STDOUT.
      use warnings; use strict; use Symbol qw(gensym); use IPC::Open3; my $out = gensym(); my $err = gensym(); my $cmd = 'dir 1>&2'; my $pid = open3(undef, $out, $err, $cmd); 1 while <$out>; 1 while <$err>; waitpid $pid, 0;

        You're right. You'd have to doing something like:

        my $t1 = async{ 1 while <$out> }; my $t2 = async{ 1 while <$err> }; $_->join for $t1, $t2; ...

        However, if your redirecting stdout to stderr, is there any point in reading stdout? And if you're going to discard the output without looking at it, why not just dump the whole lot to nul and have done with it?


        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: waitpid on Win32 ... wait forever
by ikegami (Patriarch) on May 08, 2009 at 07:04 UTC
    The presented code works fine for me using ActivePerl 5.6.0, 5.6.1, 5.8.0, 5.8.8, 5.8.9 and 5.10.0 on WinXP. Could it be that a pipe fills up when the actual program is used?
      The presented code works fine for me

      Yep, me too :-)
      Seems that the contents of $cmd (which I changed just prior to posting) can have an effect. Try instead with:
      my $cmd = 'dir';
      Cheers,
      Rob
        The dir command works fine for me until I chdir to a larger directory, at which point dir never completes because it blocks writing to the full pipe attached to STDOUT. Just like I predicted.
Re: waitpid on Win32 ... wait forever
by december (Pilgrim) on May 08, 2009 at 08:07 UTC

    I haven't been using Windows for over 10 years so I'm not entirely sure, but it might be possible that "cd" isn't an actual command but some sort of built-in shell function in command.com or whatever Windows uses these days. So maybe you get no PID at all, or the PID of the parent (the shell)?

    Either way, "cd" might be a special case. Unless this really is what you want to do, I suggest you try using some other command.

      I suggest you try using some other command

      Yes, when I first posted I was under the (mistaken) impression that *all* commands would hang. Just now, I'm starting to look at other commands - some of which hang, some of which don't.

      On my MinGW-built perl, a command of 'gcc -v' hangs, but 'gcc -o test.exe test.c' doesn't hang, and the executable gets built.

      Even on my VC7-built perl, a command of 'cl -o try.exe try.c /nologo' seems to work fine - which is surprising as that command is very similar to the command in 00_ptr_cast.t that *does* hang.
      00_ptr_cast.t can be viewed here for anyone who wants to take a look at it.

      Cheers,
      Rob
Re: waitpid on Win32 ... wait forever
by syphilis (Archbishop) on May 09, 2009 at 00:55 UTC
    Submitted a Net-SSLeay bug report containing this patch which, hopefully, fixes the problem I was having with that distro in a portable fashion:
    --- 00_ptr_cast.t_orig Sat May 9 09:51:39 2009 +++ 00_ptr_cast.t Sat May 9 10:31:59 2009 @@ -17,8 +17,12 @@ my $err = gensym(); my @extraargs; -push(@extraargs, '/nologo') if $^O eq 'MSWin32' && $Config{cc} eq 'cl +'; -my $cmd = "$Config{cc} -o $output $input " . join(' ', @extraargs); +my $cmd; +if($^O eq 'MSWin32' && $Config{cc} eq 'cl') { + push(@extraargs, '/nologo ' . $Config{libs}); + $cmd = "$Config{cc} /Fe$output $input " . join(' ', @extraargs); +} +else {$cmd = "$Config{cc} -o $output $input " . join(' ', @extraargs) +} diag( "compiling test program with: $cmd" ); my $pid = open3(undef, $out, $err, $cmd); waitpid $pid, 0;
    Cheers,
    Rob

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://762762]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2024-04-19 06:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found