#! /usr/bin/env perl use strict; use warnings; use Getopt::Long; $| = 1; # unbuffered STDOUT # save command and cmdline arguments for later re-use # because GetOptions modifies @ARGV my @cmdline = ( $0, @ARGV ); GetOptions( \my %OPT, 'timeout=i', ) or exit 255; die "(E) No timeout specified.\n" unless $OPT{timeout}; my @command = @ARGV; my $pid = open my $pipe, '-|', @command or die "(E) Could not open pipe to command '@command': $!"; print "pid $pid : @command\n"; while ( 1 ) { my $line; # read from $pipe; must be successful within $OPT{timeout} seconds eval { local $SIG{ALRM} = sub { die "alarm\n"; }; alarm $OPT{timeout}; $line = <$pipe>; alarm 0; }; # timeout exceeded if ( $@ ) { die "(E) error in alarm...\n" if $@ ne "alarm\n"; print "ALARM received!\n"; exec( @cmdline ) or die "(E) Could not re-execute myself: $!"; } # just in time else { print "READ: $line"; } } __END__