perl - Signal handler not working with double eval -
i have code timeout long-running process (sleep in case):
#!/usr/bin/env perl use strict; use warnings; die "usage: $0 sleep timeout\n" unless @argv == 2; ( $sleep, $timeout ) = @argv; $|++; eval { local $sig{alrm} = sub { die "timeout\n" }; alarm $timeout; eval { # long-running process print "going sleep ... "; sleep $sleep; print "done\n"; }; alarm 0; # cancel timeout }; die $@ if $@; when run ./alarm 5 2, expect die saying "timeout". exits 0 , says nothing. works expected when remove inner eval block (not block's content, eval) though. can explain why that? thanks.
because trap error in first eval block , second eval block not have exception , clears $@.
eval { local $sig{alrm} = sub { die "timeout\n" }; alarm $timeout; eval { # long-running process print "going sleep ... "; a: sleep $sleep; print "done\n"; }; b: alarm 0; # cancel timeout c:}; die $@ if $@; $sleep > $timeout, @ a: program throws sigalrm. signal caught local signal handler , calls die "timeout\n". perl sets $@ "timeout\n" , resumes execution @ b:. program makes c: without additional errors. since outer eval block completed normally, perl clears $@, , final die statement not execute.
to seems want do, either
- don't use
evalon outer block - put
die $@ if $@call @ end of outer block