http://www.perlmonks.org?node_id=435766

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

Wise Brothers and Sisters in Perl I beg your assistance

I have a perl script that queries an Oracle database using sqlplus on Win2003. The perl script is run by a Tivoli monitor that has a hard time limit of 120 seconds. Sometimes the SQL plus fails to return, the Tivoli monitor times out and a perl process is left hanging around waiting on sqlplus.

I can not use DBI due to local managment decision

What I want is to run the sqlplus command and if it has not returned after 110 seconds kill it and return an appropriate error to Tivoli. If it does complete in 110 seconds I need to capture STDOUT and process it. I thought this should be easy.

I have tried using $SIG{ALRM} and alarms, they are not implemented in Active State on Windows.

I have tried using win32::Process and grabbing STDOUT with no luck, here is my test code

#!/usr/bin/perl use strict; use warnings; use Win32::Process; use Win32; $|++; #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # spawn process #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ my $process="c:\\perl\\bin\\perl.exe"; my $output="nothing"; open OUT, ">", \$output; select OUT; my $ProcObj; Win32::Process::Create ( $ProcObj, $process, "perl printer.pl 1 2 3", 0, NORMAL_PRIORITY_CLASS, "." ) or die "Create process failed: $!"; #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # wait 10 seconds for process to finish #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ unless ( $ProcObj->Wait(10000) ) # waits for 10,000 milliseconds { #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # process has not completed, so return # result for monitoring probe and kill # wntmon process #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ print "-1"; $ProcObj->Kill(2001); } print "Ball cocks\n"; select STDOUT; print "output was: $output\n"; __END__ # printer.pl just prints the @ARG array it gets # output is this C:\PERL\bin>perl test_proc.pl this was called with: 1, 2, 3 output was: Ball cocks
I also found others have tried to follow this via dolorosa capturing STDOUT after Win32::Process::Create()

And finally I thought open a handle to the process and use select but the results of my search were rather off-putting IO::Select on Windows, stdin-socket without fork()?? and RE: stdin-socket without fork()??

What is the normal way to do this under Windows ? Do I need to fork and set up some form of IPC to get the results back ? Would I be OK to spawn a thread and use a shared data structure to get the results from the thread ? What is considered best practice ? One last caveat, this script has to run on Unix too so the less different the behaviour can be for the two OSes the happier I shall be, though I do expect I will have to write a sub for each OS.

My Gratitude in advance,
R.

Pereant, qui ante nos nostra dixerunt!