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; }