sub spawn { my ($timeout, @cmd) = @_; defined( my $child_pid = open(CHILD_OUTPUT, "-|" ) or die "fork: $!"; if ($child_pid) { # parent eval { local $SIG{ALRM} = sub { timeout($child_pid); }; alarm $timeout; while () { # log it } close(CHILD_OUTPUT) or warn "process $child_pid exited: $?"; alarm 0; }; if ($@) { print "oops: $@"; } } else { # child exec @cmd or die "exec: $!"; } }