Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

fork and open3 on Win32

by this_hamster (Initiate)
on Apr 28, 2001 at 06:19 UTC ( [id://76335]=perlquestion: print w/replies, xml ) Need Help??

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

In the below perl script, I fork, then have the child start "cat" via open3(). The child does some I/O with the "cat" process, then exits. I'm using Cygwin's cat.exe .
my $CMD = 'cat'; use IO::Handle; use IPC::Open3 qw( open3 ); use strict; my $pid = fork(); if ( !defined($pid) ) { die( "$$: Fork failed: $!\n" ); } # parent if ( $pid ) { print( "$$ FORKED $pid\n" ); } # child else { my( $pw, $pr, $pe, $pipe ); foreach $pipe ( $pw, $pr, $pe ) { $pipe = new IO::Handle; } my $pipe_pid = open3( $pw, $pr, $pe, $CMD ) or die( "$$: failed to handle to $CMD: $!\n" ); print( "$$:\tpipe pid = $pipe_pid\n"); $pw->print( "hostinfo\n" ); $pw->print( "quit\n" ); print( "$$: out: ", $pr->getline(), "\n" ); exit(0); } waitpid( $pid, 0 ); print( "$$ caught $pid: $?\n" ); print( "PARENT $$ exiting\n" );
This works fine on Unix (perl 5.6.0):
  $ ./t_iohand2
  8629 FORKED 8630
  8630:   pipe pid = 8631
  8630: out: hostinfo

  8629 caught 8630: 0
  PARENT 8629 exiting
However, it does this on Win32 (ActiveState Perl 5.6.0-623 and 5.6.1-625):
    D:>perl -w t_iohand2
    304 FORKED -1392
    am I in cat?
    #hangs here, so I type in "am I in cat?" to see if this is cat's STDIN/STDOUT
    am I in cat? #cat repeated the line back
    (hit ^D here to end cat)
    Use of uninitialized value in print at t_iohand2 line 35.
    -1392: pipe pid = 1400
    -1392: out:
    304 caught -1392: 0
    PARENT 304 exiting

The process tree for the Win32 output looks like this: 304 -(fork)-> -1392 -(open3)-> 1400

It looks like the STDIN/STDOUT of process 1400 (the open3() child) is getting mixed up with the STDIN/STDOUT of it's parent, -1392.

I'm using "cat" as an example here. In the actual script, $CMD is the path to a shell-like program (similar to csh) running on Win32.

This works fine on Cygwin perl 5.6.1-1, but my project wants to use ActiveState for a variety of reasons.

Thanks for any input!

Replies are listed 'Best First'.
(tye)Re: fork and open3 on Win32
by tye (Sage) on Apr 28, 2001 at 10:11 UTC

    fork in Win32 Perl is just simulated using threads and separate interpreter instances. So, no, after fork you still only have one process so, in particular, all file handles are shared.

    Instead of using fork, you need to create a new process. Something like:

    #!/usr/bin/perl -w my $CMD = 'cat'; use IO::Handle; use IPC::Open3 qw( open3 ); use strict; my $pid; if( $^W =~ /mswin32/i ) { unless( @ARGV && $ARGV[0] =~ /^-child$/i ) { $pid= system( 1, qq("$^X" "$0" -child) ) or die "system() failed: $!\n"; } else { shift @ARGV; $pid= 0; } } else { $pid = fork(); if ( !defined($pid) ) { die( "$$: Fork failed: $!\n" ); } } # parent if ( $pid ) { #...
    (not fully tested)

            - tye (but my friends call me "Tye")
Re: fork and open3 on Win32
by Mungbeans (Pilgrim) on Apr 30, 2001 at 13:01 UTC
    Maybe just me but I found fork a little flakey under Windows.

    It's not portable but you could use this inside an OS specific flag to create a separate process:

    use Win32::Process; my $ProcessObj; Win32::Process::Create($ProcessObj, "c:\\Perl\\bin\\perl.exe ", " $temp_file ", ### Script to execute 1, ### If set to 0 this prevents children ### writing to STDOUT which is BAD... NORMAL_PRIORITY_CLASS, ".") || die ErrorReport();

    Look up the docs on win32::process and do a search on this site (the dos are a little hard to read, IMHO, so be prepared to experiment). You should be able to get the two process communicating through temporary files if you can't get them to cohabit happily on STDIN.

      Hmmm - missed something.

      This will run in the background, and the parent won't wait for the child to complete. $temp_file could contain the name of the script you are running with flags -child=1 -parent=$$ or somesuch.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2024-04-24 11:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found