I'm seeing some real weirdness in Perl under Windows.

Apparently select only works with sockets (see 67963), so instead of using open("x |") I'm trying to use socketpair, POSIX::dup2, and exec. It's working fine, but when I dup2 one end of the socketpair to STDOUT in the child process, somehow STDOUT in the parent process gets connected to the same place, after a brief delay during which it works normally.

Here's seltest.pl:

#!perl -w use strict; use IO::Select; use Socket; use POSIX; socketpair(SOCK_READ,SOCK_WRITE,AF_UNIX,SOCK_STREAM,PF_UNSPEC) or die "Couldn't create socket pair: $!\n"; print "STDOUT print 1.\n"; if (!defined(my $f = fork())) { die "Fork error: $!\n"; } elsif (!$f) { # child close(SOCK_READ); warn "CHILD PID: $$\n"; close(STDOUT) or die "Couldn't close STDOUT: $!\n"; POSIX::dup2(fileno(SOCK_WRITE),1); sleep(100) while(1); } # parent close(SOCK_WRITE); warn "Parent is PID $$\n"; # We can't reliably print to STDOUT after this point (at some point, # it will start going to the socket) #sleep(5); print "STDOUT print 2.\n"; my $sel = IO::Select->new; $sel->add(\*SOCK_READ) or die "Couldn't add pipe to IO::Select: $!\n"; print "STDOUT print 3.\n"; while (1) { print "STDOUT print 4.\n"; warn "DEBUG: select on ",$sel->count," handles.\n"; my @ready = $sel->can_read(10); warn "Parent DEBUG: ",scalar(@ready)," handles readable.\n"; print "STDOUT print 5.\n"; foreach my $rh (@ready) { my $line=<$rh>; warn "Parent read $rh: $line"; } sleep(3); }
The output from this on Windows is:
STDOUT print 1. Parent is PID 1996 STDOUT print 2. STDOUT print 3. STDOUT print 4. DEBUG: select on 1 handles. CHILD PID: -1860 Parent DEBUG: 0 handles readable. DEBUG: select on 1 handles. Parent DEBUG: 1 handles readable. Parent read GLOB(0x1b2cee8): STDOUT print 5. DEBUG: select on 1 handles. Parent DEBUG: 1 handles readable. Parent read GLOB(0x1b2cee8): STDOUT print 4.

As you can see, after a short time the parent starts reading its own input on the handle that should be coming from the child. If you uncomment the sleep(5), then all output from the parent goes to the wrong place. On Unix it behaves as I expected, with all output going to the parent's STDOUT and select nevere returning anything.

Anybody have any idea what's going on here? Or is this just what I should expect when I try to program Perl on Windows as if it were Unix?


In reply to Windows weirdness after fork, dup2 by sgifford

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.