The trick is not to propagate the signal, but instead set a flag, continue with the destructors, and handle the signal when it is safe to do so. This is in keeping with the general philosophy that signal handlers should be very simple -- especially in Perl. (I can't recall where I read this; perhaps someone can provide a pointer to more details.)
#!/usr/bin/perl -l
use strict;
use warnings;
my $sig;
END
{
local $?;
print "Handling signal $sig" if $sig;
}
$SIG{INT} = sub { $sig = shift; print "Got signal $sig" };
{
package Foo;
sub new { bless [$_[1]], $_[0] }
sub DESTROY { print shift->[0], "->DESTROY()"; sleep 2 }
}
my $foo = new Foo "foo";
my $bar = new Foo "bar";
print "Now press Ctrl-C";
Update: Thanks to Mr_Person for finding the details.