END { kill 'INT', $$ }
sub DESTROY { print "@{$_[0]}\n"; exit(14); }
my $a = bless [1];
my $b = bless [2, $a];
####
sub DESTROY { print "@{$_[0]}\n"; exit(14); }
my $a = bless [1];
my $b = bless [2, $a];
my $c = bless [3, $b];
####
3 main=ARRAY(0x80f00c4)
1
####
my $cleaning_up;
sub DESTROY {
print "DESTROY @{$_[0]}\n";
my $id = $_[0][0];
@{$_[0]} = ();
print "CLEAN $id\n";
return if $cleaning_up++;
exit(14);
}
my $a = bless [1];
my $b = bless [2, $a];
my $c = bless [3, $b];
####
DESTROY 3 main=ARRAY(0x80f00c4)
DESTROY 2 main=ARRAY(0x80f01b4)
DESTROY 1
CLEAN 1
####
use POSIX;
{
# Fork off a parent whose role is to convert the exit status.
my $pid = fork;
defined($pid) or die "Fork failed because $!";
if($pid) {
{
# TBD: This really ought to be `sub { kill $_[0], $pid }'
# instead of "IGNORE", but that does bad things on
# ctrl-C, probably because the child gets the signal
# twice.
local $SIG{INT} = "IGNORE";
waitpid($pid,0);
}
kill &POSIX::WTERMSIG($?), $$
if &POSIX::WIFSIGNALED($?);
my $status = &POSIX::WEXITSTATUS($?);
if(0x80 < $status && $status < 0xC0) {
kill $status - 0x80, $$;
}
POSIX::_exit($status);
}
}
my $termsig;
my $cleaning_up;
our $in_dtor;
sub DESTROY {
# NOTE: Signals that arrive in this method but outside the eval
# are still a problem.
my $id = $_[0][0];
local ($@, $?);
eval {
my $sub_dtor = $in_dtor;
local $in_dtor = 1;
print "DESTROY @{$_[0]}\n";
my $id = $_[0][0];
@{$_[0]} = ();
print "CLEAN $id\n";
};
warn "Failed to deallocate $id: $@" if $@;
return unless $termsig;
return if $in_dtor || $cleaning_up++;
exit(14);
}
eval {
local $SIG{INT} = sub { $termsig = $_[0]; die "SIG$_[0]\n" };
{
my $a = bless [1];
my $b = bless [2, $a];
my $c = bless [3, $b];
}
0; # Must be here to make handler go out of scope last!
};
if($@) {
die $@ unless $@ =~ /^SIG(\w+)$/;
}
END {
if($termsig) {
use Config;
my @sigs = split(' ', $Config{sig_name});
my $i=0;
$i++ while $sigs[$i] ne $termsig;
$? = 0x80 + $i;
}
}