TGI has asked for the wisdom of the Perl Monks concerning the following question:
I've been working on a long running script that has to call some leaky libraries (which I do not control and can't fix) to do its job. "Simple enough", I think, "I'll segment out the leaky crud, put it a separate program. The main program spawns a child to process the data, gets the result and terminates the child when its done." Instant irrelevance to the leak, right? Wrong.
I've tried a number of things along the lines of:
open (my $SAVEDIN, '<&', STDIN ) or die "$!"; my ($READ, $WRITE); pipe( $READ, $WRITE ); open ( STDIN, '<&', $READ ) or die "$!"; my $winproc; Win32::Process::Create( $winproc, 'C:\\perl\\bin\\perl.exe', 'myscript.pl', 1, # inherit handles '.' ) or die "Process did not start"; open( STDIN, '<&', $SAVEDIN ) or die "$!";
The child process starts up fine. But the child does not inherit STDIN or STDOUT. I've tried localizing STDIN and STDOUT instead of overriding and restoring them manually.
I even tried an example from a very old TPJ (Fall 1997) article on the wonders of new and exciting Win32 Perl, and that does not work either. The child process does not inherit STDIO.
The Server:
use Win32::Process; %Data = ( one => 1, two => 2, three => 3, ); pipe(READ, WRITE); select(WRITE); $| = 1; select(STDOUT); open(SAVEIN, "<&STDIN") || die "Can't save STDIN\n"; open(STDIN, "<&READ") || die "Can't redirect STDIN\n"; select(STDIN); $| = 1; select(STDOUT); Win32::Process::Create( $Process, "c:\\perl\\bin\\perl.exe", "tpjclient.pl", 1, NORMAL_PRIORITY_CLASS, "." ); open(STDIN, "<&SAVEIN"); close(SAVEIN); close(READ); print "$0: Sending variables to child...\n"; foreach $Temp (keys(%Data)){ print "$0:\t$Temp=$Data{$Temp}\n"; print WRITE "\$Data{$Temp}=$Data{$Temp};\n"; } print "$0: Finished sending variables.\n"; close(WRITE); print "$0: About to terminate. Waiting for <RETURN>...\n"; <STDIN>; print "$0: End.\n";
The Client:
print "$0: Starting.\n"; print "$0: Reading in variables...\n"; while(<STDIN>) { eval($_); print "$0: \t$_"; } print "$0: Finished reading variables.\n"; print "$0: Dumping variables...\n"; foreach $Temp (keys(%Data)){ print "$0:\t$Temp=$Data{$Temp}\n"; } print "$0: End.\n";
I'm using ActivePerl 5.8.8 on a WinXP SP3 system.
At this point I'll take any suggestions from "You idiot you forgot to do wibble, which it says in perlfoo", to "use a network socket".
It's worth mentioning that my goal is to integrate my solution with a Tk GUI. Since fileevent() is broken on Win32, I'll need to arrange for a non-blocking method of IO--any solution must work with select() or the O_NONBLOCK ioctl/fcntl flag--because I'll have to poll my child process while it is running. I've seen suggestions to use shared memory to pass data between Tk parent processes and their children. I have avoided using shared memory because of the cruddiness of the code I am sequestering--the last thing I need is a contagion of crap coming into my main program. Perhaps this is a baseless concern?
TGI says moo
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Win32 Perl: inheriting redirected STDIN and STDOUT in a child process (eof?)
by tye (Sage) on Oct 22, 2008 at 18:29 UTC | |
|
Re: Win32 Perl: inheriting redirected STDIN and STDOUT in a child process
by Corion (Patriarch) on Oct 22, 2008 at 18:04 UTC | |
by BrowserUk (Patriarch) on Oct 22, 2008 at 18:18 UTC | |
by tye (Sage) on Oct 22, 2008 at 18:49 UTC | |
by TGI (Parson) on Oct 23, 2008 at 16:32 UTC | |
by BrowserUk (Patriarch) on Oct 23, 2008 at 17:36 UTC |