The corrosion of Aaron Stone

about

Handling exit within an eval

So I’ve run into a problem with mod_perlite, and it’s that I cannot just override Perl’s exit function with a straight perl_destruct call, a longjmp back to the Apache handler, or anything else at all.

Here’s my favorite…

bar.pl

exit;

Foo.pm

package Foo;

sub new {
  return bless { };
}

sub DESTROY {
  print "Foo is destroyed\n";
}

1;

foo.pl

use Foo;

my $foo = Foo->new;

print "I have a foo!\n";

BEGIN { *CORE::GLOBAL::exit = sub { goto EXIT; }; }

eval {
  bar("bar.pl");
}; if ($@) {
  print "$@ happens\n";
}

print "And I'm still here\n";

sub bar {
  eval require $_[0];
  EXIT:
  print "Exiting!\n";
  goto REALLY_EXIT;
}

REALLY_EXIT:

Yep, that actually works!

I have a foo!  
Exiting!  
Foo is destroyed.