hide random home http://www.fmi.uni-passau.de/archive/doc/unix/perl/faq/2.21.html (Einblicke ins Internet, 10/1995)

How can I do an atexit() or setjmp()/longjmp() in Perl?

How can I do an atexit() or setjmp()/longjmp() in Perl?


    Perl's exception-handling mechanism is its eval operator.  You 
    can use eval as setjmp and die as longjmp.  Here's an example
    of Larry's for timed-out input, which in C is often implemented
    using setjmp and longjmp:

          $SIG{ALRM} = TIMEOUT;
          sub TIMEOUT { die "restart input\n" }

          do { eval { &realcode } } while $@ =~ /^restart input/;

          sub realcode {
              alarm 15;
              $ans = <STDIN>;
              alarm 0;
          }

   Here's an example of Tom's for doing atexit() handling:

        sub atexit { push(@_exit_subs, @_) }

        sub _cleanup { unlink $tmp }

        &atexit('_cleanup');

        eval <<'End_Of_Eval';  $here = __LINE__;
        # as much code here as you want
        End_Of_Eval

        $oops = $@;  # save error message

        # now call his stuff
        for (@_exit_subs) { &$_() }

        $oops && ($oops =~ s/\(eval\) line (\d+)/$0 .
            " line " . ($1+$here)/e, die $oops);

    You can register your own routines via the &atexit function now.  You
    might also want to use the &realcode method of Larry's rather than
    embedding all your code in the here-is document.  Make sure to leave
    via die rather than exit, or write your own &exit routine and call
    that instead.   In general, it's better for nested routines to exit
    via die rather than exit for just this reason.

    In Perl5, it will be easy to set this up because of the automatic
    processing of per-package END functions.

    Eval is also quite useful for testing for system dependent features,
    like symlinks, or using a user-input regexp that might otherwise
    blowup on you.