Apologies if my description was unclear.
I have a Perl run harness - it is used to run everything. Its purpose is to ensure complete control of the external environment for everything we execute. It logs info about each process including mem usage, time elapsed etc. It ensures that the STDOUT and STDERR of each process are captured to logs, and only sent to a terminal if one is present. It detects abnormal termination and sends out emails to sysops etc.
This run harness uses IPC::Open3 to run the child process, and monitors the childs STDOUT and STDERR using non-blocking reads. It passes its own STDIN to the child using the documented <&STDIN syntax - this has the effect of passing STDIN through to the child process, so that if the child needs to read from STDIN it is reading directly from the terminal. It also has the effect of closing the run harness's STDIN - but that's ok - the run harness is trying to be as transparent as possible.
Once the child process PID is available, the run harness opens up a log into which it will write the STDOUT and STDERR of the child process. This open issues a warning, because the next available file handle happens to be 0.
The run harness is lean and mean, and never assumes that fh 0 is STDIN - it uses nicely scoped filehandles, never the old STDIN *STDIN etc.
some code? well ok - here is an incomplete snippet:
use strict;
use FileHandle;
use IPC::Open3;
use IO::Select;
my @command = @ARGV;
# --------------------------------------------------------------------
+----------
# File handles that child process will write to
# Dont use them for anything until AFTER the open3() call,
# as they dont get filenos until then!
my $childSTDOUT = FileHandle->new;
my $childSTDERR = FileHandle->new;
# --------------------------------------------------------------------
+----------
# runs the child process, hooking us up to its FHs
my $childPID = open3("<&STDIN", $childSTDOUT, $childSTDERR, @command);
if ( !$childPID ) {
_log("RUN ERROR: COMMAND='@command' open3/exec failed: $!");
};
# This gives a new warning under 5.8.3 as it reuses 0 which was closed
+ by open3
my $fhLog = FileHandle->new(">>$childPID.log")
or _log("RUN WARNING: Failed to create $childPID.log because '$!'");
_log("RUN BEGIN: PID=$childPID COMMAND='@command'");
# select based non-blocking IO
my $sel = IO::Select->new();
$sel->add($childSTDOUT);
$sel->add($childSTDERR);
# non-blocking select timeouts (seconds). Arbitary
my ($line, $bytes, $total_bytes);
# --------------------------------------------------------------------
+----------
# Loop reading child output
# control flags
my $childLives = 1;
my $childActivity = 0;
while ($childLives) {
my @read = $sel->can_read(60);
my $should = 0;
my $bytes = 0;
foreach my $fh ( @read ) {
$should++;
# _read read from $fh and writes to $fhLog
$bytes += _read($fh,$fhLog);
}
$childLives = 0 if $should and not $bytes;
}
Hope thats enough for you to get a handle on this :)
My gripe is that I dont care that fh 0 has been reused - how do I tell IO::File to not emit this new 5.8.3 warning?
TIA
Jeff |