... $SIG{ALRM} = sub { die 'timeout' }; ... do_work(); sub do_work { ... eval { ... } ... die $@ if 'timeout' eq $@; ... } #### my $timed_out = 1; TIMEOUT_BLOCK_WITH_UNIQUE_LABEL: { local $SIG{ALRM} = sub { last TIMEOUT_BLOCK_WITH_UNIQUE_LABEL; }; my $err; eval { alarm( $seconds ); do_work(); 1 } or do { $err = $@ || 'Unknown error'; } alarm( 0 ); die $err if $err; $timed_out = 0; }