GIF89a=( �' 7IAXKgNgYvYx\%wh&h}t�h%�s%x�}9�R��&�0%� (�.��5�SD��&�a)�x5��;ͣ*ȡ&ղ)ׯ7׵<ѻ4�3�H֧KͯT��Y�aq��q��F� !� ' !� NETSCAPE2.0 , =( ��pH,�Ȥr�l:xШtJ�Z�جv��z��xL.:��z�n���|N�����~�������& !�0`9R�}��"�"a:S�~x��������g���E�������R���E����B�� ��ȸ��D���"�Ů� �H��L��D٫D�B�����D���T���H �G��A R�ڐ |�� ٭&��E8�S�kG�A�px�a��� R2XB��E8I���6X�:vT)�~��q�賥��"F~%x� � 4#Z�0O|-4Bs�X:= Q� Sal��yXJ`GȦ|s h��K3l7�B|�$'7Jީܪ0!��D�n=�P� ����0`�R�lj����v>���5 �.69�ϸd�����nlv�9��f{���Pbx �l5}�p� ��� �3a���I�O����!ܾ���i��9��#��)p�a ޽ �{�)vm��%D~ 6f��s}Œ�D�W E�`!� �&L8x� �ܝ{)x`X/>�}m��R�*|`D�=�_ ^�5 !_&'a�O�7�c��`DCx`�¥�9�Y�F���`?��"� �n@`�} lď��@4>�d S �v�xN��"@~d��=�g�s~G��� ���ud &p8Q�)ƫlXD����A~H�ySun�j���k*D�LH�] ��C"J��Xb~ʪwSt}6K,��q�S:9ت:���l�@�`�� �.۬�t9�S�[:��=`9N����{¿�A !R�:���6��x�0�_ �;������^���#����!����U���;0L1�����p% A��U̬ݵ��%�S��!���~`�G���� ���=4�np�3���������u�u�ٮ|%2�I��r�#0��J``8�@S@5� ���^`8E�]�.�S���7 � �0�j S�D� z���i�S�����!���l��w9*�D�I�nEX��� &A�Go�Qf��F��;���}�J����F5��Q|���X��T��y���]� o ��C=��:���PB@ D׽S�(>�C�x}`��xJЬ�۠��p+eE0`�}`A �/NE�� �9@��� H�7�!%B0`�l*��!8 2�%� �:�1�0E��ux%nP1�!�C)�P81l�ɸF#Ƭ{����B0>�� �b�`��O3��()yRpb��E.ZD8�H@% �Rx+%���c� ���f��b�d�`F�"8�XH"��-�|1�6iI, 2�$+](A*j� QT�o0.�U�`�R�}`�SN����yae�����b��o~ S)�y�@��3 �tT�0�&�+~L�f"�-|�~��>!�v��~�\Q1)}@�}h#aP72�"�$ !� " , =( &7IAXG]KgNgYvYxR"k\%w]'}h}t�h%�g+�s%r.m3ax3�x�}9��&��+�!7�0%� (�.�SD��&��;�"&ײ)׻4��6�K� �@pH,�Ȥr�l:xШtJ�Z�جv��z��xL.:��z�n���|N�����~�������& !�0`9R�}��"�"a:S�~x��������g �� E �� �������E �´��C���ǶR��D��"Ʒ�ʱH��M��GڬD�B����D��T����G���C�C� l&�~:'�tU�6ɹ#��)�'�.6�&��Ȼ K(8p0N�?!�2"��NIJX>R��OM '��2�*x�>#n� �@<[:�I�f ��T���Cdb��[�}E�5MBo��@�`@��tW-3 �x�B���jI�&E�9[T&$��ﯧ&"s��ȳ����dc�UUρ#���ldj?����`\}���u|3'�R]�6 �S#�!�FKL�*N E���`$�:e�YD�q�.�촁�s \-�jA 9�����-��M[�x(�s��x�|���p��}k�T�DpE@W� ��]k`1� ���Yb ��0l��*n0��"~zBd�~u�7�0Bl��0-�x~|U�U0 �h�*HS�|��e"#"?vp�i`e6^�+q��`m8 #V�� ��VS|`��"m"сSn|@:U���~`pb�G�ED����2F�I�? >�x� R� ��%~jx��<�a�9ij�2�D��&: Z`�]w���:�6��B�7eFJ|�ҧ�,���FǮcS�ʶ+B�,�ܺN���>PAD�HD��~���n��}�#�� Q��S���2�X�{�k�lQ�2�����w�|2� h9��G�,m���3��6-��E�L��I�³*K���q�`DwV�QXS��peS��� qܧTS����R�u �<�a�*At�lmE� � ��N[P1�ۦ��$��@`��Dpy�yXvCAy�B`}D� 0QwG#� �a[^�� $���Ǧ{L�"[��K�g�;�S~��GX.�goT.��ư��x���?1z��x~:�g�|�L� ��S`��0S]P�^p F<""�?!,�!N4&P� ����:T�@h�9%t��:�-~�I<`�9p I&.)^ 40D#p@�j4�ج:�01��rܼF2oW�#Z ;$Q q  �K��Nl#29 !F@�Bh�ᏬL!XF�LHKh�.�hE&J�G��<"WN!�����Y@� >R~19J"�2,/ &.GXB%�R�9B6�W]���W�I�$��9�RE8Y� ��"�A5�Q.axB�&ة�J�! �t)K%tS-�JF b�NMxL��)�R��"���6O!TH�H� 0 !� ) , =( &AXKgNgYvYxR"k\%wh&h}h%�g+�s%r.x3�x�}9��&��+�R,�!7�0%� (�.��5��&�a)��;�"&ף*Ȳ)ׯ7׻4�3��6�H֧KͻH�T��Y��q��h� ��pH,�Ȥr�l:xШtJ�Z�جv��z��xL.:��z�n���|N�����~�������& !�0`9R�}��"�"a:S�~x��������g �� E$����� � ����$E$��"��D� � ������R��C��� E ��H�M��G�D� �B��ϾD��a��`1r��Ӑ�� �o~�zU!L�C'�yW�UGt����ll�0���uG�)A�s[��x� �xO%��X2�  P�n:R/��aHae+�Dm?# ǣ6�8�J�x�Di�M���j���5oQ7�- <! *�l��R2r/a!l)d� A"�E���� &� ;��c �%����b��pe~C"B���H�eF2��`8qb�t_`ur`e� w�u3��Pv�h""�`�Íx�LĹ��3� �~ֺ�:���MDfJ� �۵�W�%�S�X �؁)�@��:E��w�u�Sxb8y\m�zS��Zb�E�L��w!y(>�"w�=�|��s�d �C�W)H�cC$�L �7r.�\{)@�`@ �X�$PD `aaG:���O�72E�amn]�"Rc�x�R� &dR8`g��i�xLR!�P &d����T���i�|�_ � Qi�#�`g:��:noM� :V �)p����W&a=�e�k� j���1߲s�x�W�jal|0��B0�, \j۴:6���C ��W��|��9���zĸV {�;��n��V�m�I��.��PN� ����C��+��By�ѾHŸ:��� 7�Y�FTk�SaoaY$D�S���29R�kt� ��f� ��:��Sp�3�I��DZ� �9���g��u�*3)O��[_hv ,���Et x�BH� �[��64M@�S�M7d�l�ܶ5-��U܍��z�R3Ԭ3~ ��P��5�g: ���kN�&0�j4���#{��3S�2�K�'ợl���2K{� {۶?~m𸧠�I�nE�='����^���_�=��~�#O���'���o..�Y�n��CSO��a��K��o,���b�����{�C�� "�{�K ��w��Ozdը�:$ ���v�] A#� ���a�z)Rx׿ƥ�d``�w-�y�f�K!����|��P��=�`�(f��'Pa ��BJa%��f�%`�}F����6>��`G"�}�=�!o`�^FP�ةQ�C���`(�}\�ݮ ��$<��n@dĠE#��U�I�!� #l��9`k���'Rr��Z�NB�MF �[�+9���-�wj���8�r� ,V�h"�|�S=�G_��"E� 0i*%̲��da0mVk�):;&6p>�jK ��# �D�:�c?:R Ӭf��I-�"�<�="��7�3S��c2RW ,�8(T"P0F¡Jh�" ; 403WebShell
403Webshell
Server IP : 173.249.157.85  /  Your IP : 18.119.10.46
Web Server : Apache
System : Linux server.frogzhost.com 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64
User : econtech ( 1005)
PHP Version : 7.3.33
Disable Function : NONE
MySQL : OFF  |  cURL : OFF  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /proc/self/root/usr/share/perl5/vendor_perl/autodie/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /proc/self/root/usr/share/perl5/vendor_perl/autodie/exception.pm
package autodie::exception;
use 5.008;
use strict;
use warnings;
use Carp qw(croak);

our $VERSION = '2.16'; # VERSION: Generated by DZP::OurPkg:Version
# ABSTRACT: Exceptions from autodying functions.

our $DEBUG = 0;

use overload
    q{""} => "stringify"
;

# Overload smart-match only if we're using 5.10

use if ($] >= 5.010), overload => '~~'  => "matches";

my $PACKAGE = __PACKAGE__;  # Useful to have a scalar for hash keys.

=head1 NAME

autodie::exception - Exceptions from autodying functions.

=head1 SYNOPSIS

    eval {
        use autodie;

        open(my $fh, '<', 'some_file.txt');

        ...
    };

    if (my $E = $@) {
        say "Ooops!  ",$E->caller," had problems: $@";
    }


=head1 DESCRIPTION

When an L<autodie> enabled function fails, it generates an
C<autodie::exception> object.  This can be interrogated to
determine further information about the error that occurred.

This document is broken into two sections; those methods that
are most useful to the end-developer, and those methods for
anyone wishing to subclass or get very familiar with
C<autodie::exception>.

=head2 Common Methods

These methods are intended to be used in the everyday dealing
of exceptions.

The following assume that the error has been copied into
a separate scalar:

    if ($E = $@) {
        ...
    }

This is not required, but is recommended in case any code
is called which may reset or alter C<$@>.

=cut

=head3 args

    my $array_ref = $E->args;

Provides a reference to the arguments passed to the subroutine
that died.

=cut

sub args        { return $_[0]->{$PACKAGE}{args}; }

=head3 function

    my $sub = $E->function;

The subroutine (including package) that threw the exception.

=cut

sub function   { return $_[0]->{$PACKAGE}{function};  }

=head3 file

    my $file = $E->file;

The file in which the error occurred (eg, C<myscript.pl> or
C<MyTest.pm>).

=cut

sub file        { return $_[0]->{$PACKAGE}{file};  }

=head3 package

    my $package = $E->package;

The package from which the exceptional subroutine was called.

=cut

sub package     { return $_[0]->{$PACKAGE}{package}; }

=head3 caller

    my $caller = $E->caller;

The subroutine that I<called> the exceptional code.

=cut

sub caller      { return $_[0]->{$PACKAGE}{caller};  }

=head3 line

    my $line = $E->line;

The line in C<< $E->file >> where the exceptional code was called.

=cut

sub line        { return $_[0]->{$PACKAGE}{line};  }

=head3 context

    my $context = $E->context;

The context in which the subroutine was called by autodie; usually
the same as the context in which you called the autodying subroutine.
This can be 'list', 'scalar', or undefined (unknown).  It will never
be 'void', as C<autodie> always captures the return value in one way
or another.

For some core functions that always return a scalar value regardless
of their context (eg, C<chown>), this may be 'scalar', even if you
used a list context.

=cut

# TODO: The comments above say this can be undefined. Is that actually
# the case? (With 'system', perhaps?)

sub context     { return $_[0]->{$PACKAGE}{context} }

=head3 return

    my $return_value = $E->return;

The value(s) returned by the failed subroutine.  When the subroutine
was called in a list context, this will always be a reference to an
array containing the results.  When the subroutine was called in
a scalar context, this will be the actual scalar returned.

=cut

sub return      { return $_[0]->{$PACKAGE}{return} }

=head3 errno

    my $errno = $E->errno;

The value of C<$!> at the time when the exception occurred.

B<NOTE>: This method will leave the main C<autodie::exception> class
and become part of a role in the future.  You should only call
C<errno> for exceptions where C<$!> would reasonably have been
set on failure.

=cut

# TODO: Make errno part of a role.  It doesn't make sense for
# everything.

sub errno       { return $_[0]->{$PACKAGE}{errno}; }

=head3 eval_error

    my $old_eval_error = $E->eval_error;

The contents of C<$@> immediately after autodie triggered an
exception.  This may be useful when dealing with modules such
as L<Text::Balanced> that set (but do not throw) C<$@> on error.

=cut

sub eval_error { return $_[0]->{$PACKAGE}{eval_error}; }

=head3 matches

    if ( $e->matches('open') ) { ... }

    if ( $e ~~ 'open' ) { ... }

C<matches> is used to determine whether a
given exception matches a particular role.  On Perl 5.10,
using smart-match (C<~~>) with an C<autodie::exception> object
will use C<matches> underneath.

An exception is considered to match a string if:

=over 4

=item *

For a string not starting with a colon, the string exactly matches the
package and subroutine that threw the exception.  For example,
C<MyModule::log>.  If the string does not contain a package name,
C<CORE::> is assumed.

=item *

For a string that does start with a colon, if the subroutine
throwing the exception I<does> that behaviour.  For example, the
C<CORE::open> subroutine does C<:file>, C<:io> and C<:all>.

See L<autodie/CATEGORIES> for futher information.

=back

=cut

{
    my (%cache);

    sub matches {
        my ($this, $that) = @_;

        # TODO - Handle references
        croak "UNIMPLEMENTED" if ref $that;

        my $sub = $this->function;

        if ($DEBUG) {
            my $sub2 = $this->function;
            warn "Smart-matching $that against $sub / $sub2\n";
        }

        # Direct subname match.
        return 1 if $that eq $sub;
        return 1 if $that !~ /:/ and "CORE::$that" eq $sub;
        return 0 if $that !~ /^:/;

        # Cached match / check tags.
        require Fatal;

        if (exists $cache{$sub}{$that}) {
            return $cache{$sub}{$that};
        }

        # This rather awful looking line checks to see if our sub is in the
        # list of expanded tags, caches it, and returns the result.

        return $cache{$sub}{$that} = grep { $_ eq $sub } @{ $this->_expand_tag($that) };
    }
}

# This exists primarily so that child classes can override or
# augment it if they wish.

sub _expand_tag {
    my ($this, @args) = @_;

    return Fatal->_expand_tag(@args);
}

=head2 Advanced methods

The following methods, while usable from anywhere, are primarily
intended for developers wishing to subclass C<autodie::exception>,
write code that registers custom error messages, or otherwise
work closely with the C<autodie::exception> model.

=cut

# The table below records customer formatters.
# TODO - Should this be a package var instead?
# TODO - Should these be in a completely different file, or
#        perhaps loaded on demand?  Most formatters will never
#        get used in most programs.

my %formatter_of = (
    'CORE::close'   => \&_format_close,
    'CORE::open'    => \&_format_open,
    'CORE::dbmopen' => \&_format_dbmopen,
    'CORE::flock'   => \&_format_flock,
);

# TODO: Our tests only check LOCK_EX | LOCK_NB is properly
# formatted.  Try other combinations and ensure they work
# correctly.

sub _format_flock {
    my ($this) = @_;

    require Fcntl;

    my $filehandle = $this->args->[0];
    my $raw_mode   = $this->args->[1];

    my $mode_type;
    my $lock_unlock;

    if ($raw_mode & Fcntl::LOCK_EX() ) {
        $lock_unlock = "lock";
        $mode_type = "for exclusive access";
    }
    elsif ($raw_mode & Fcntl::LOCK_SH() ) {
        $lock_unlock = "lock";
        $mode_type = "for shared access";
    }
    elsif ($raw_mode & Fcntl::LOCK_UN() ) {
        $lock_unlock = "unlock";
        $mode_type = "";
    }
    else {
        # I've got no idea what they're trying to do.
        $lock_unlock = "lock";
        $mode_type = "with mode $raw_mode";
    }

    my $cooked_filehandle;

    if ($filehandle and not ref $filehandle) {

        # A package filehandle with a name!

        $cooked_filehandle = " $filehandle";
    }
    else {
        # Otherwise we have a scalar filehandle.

        $cooked_filehandle = '';

    }

    local $! = $this->errno;

    return "Can't $lock_unlock filehandle$cooked_filehandle $mode_type: $!";

}

# Default formatter for CORE::dbmopen
sub _format_dbmopen {
    my ($this) = @_;
    my @args   = @{$this->args};

    # TODO: Presently, $args flattens out the (usually empty) hash
    # which is passed as the first argument to dbmopen.  This is
    # a bug in our args handling code (taking a reference to it would
    # be better), but for the moment we'll just examine the end of
    # our arguments list for message formatting.

    my $mode = $args[-1];
    my $file = $args[-2];

    # If we have a mask, then display it in octal, not decimal.
    # We don't do this if it already looks octalish, or doesn't
    # look like a number.

    if ($mode =~ /^[^\D0]\d+$/) {
        $mode = sprintf("0%lo", $mode);
    };

    local $! = $this->errno;

    return "Can't dbmopen(%hash, '$file', $mode): '$!'";
}

# Default formatter for CORE::close

sub _format_close {
    my ($this) = @_;
    my $close_arg = $this->args->[0];

    local $! = $this->errno;

    # If we've got an old-style filehandle, mention it.
    if ($close_arg and not ref $close_arg) {
        return "Can't close filehandle '$close_arg': '$!'";
    }

    # TODO - This will probably produce an ugly error.  Test and fix.
    return "Can't close($close_arg) filehandle: '$!'";

}

# Default formatter for CORE::open

use constant _FORMAT_OPEN => "Can't open '%s' for %s: '%s'";

sub _format_open_with_mode {
    my ($this, $mode, $file, $error) = @_;

    my $wordy_mode;

    if    ($mode eq '<')  { $wordy_mode = 'reading';   }
    elsif ($mode eq '>')  { $wordy_mode = 'writing';   }
    elsif ($mode eq '>>') { $wordy_mode = 'appending'; }

    return sprintf _FORMAT_OPEN, $file, $wordy_mode, $error if $wordy_mode;

    Carp::confess("Internal autodie::exception error: Don't know how to format mode '$mode'.");

}

sub _format_open {
    my ($this) = @_;

    my @open_args = @{$this->args};

    # Use the default formatter for single-arg and many-arg open
    if (@open_args <= 1 or @open_args >= 4) {
        return $this->format_default;
    }

    # For two arg open, we have to extract the mode
    if (@open_args == 2) {
        my ($fh, $file) = @open_args;

        if (ref($fh) eq "GLOB") {
            $fh = '$fh';
        }

        my ($mode) = $file =~ m{
            ^\s*                # Spaces before mode
            (
                (?>             # Non-backtracking subexp.
                    <           # Reading
                    |>>?        # Writing/appending
                )
            )
            [^&]                # Not an ampersand (which means a dup)
        }x;

        if (not $mode) {
            # Maybe it's a 2-arg open without any mode at all?
            # Detect the most simple case for this, where our
            # file consists only of word characters.

            if ( $file =~ m{^\s*\w+\s*$} ) {
                $mode = '<'
            }
            else {
                # Otherwise, we've got no idea what's going on.
                # Use the default.
                return $this->format_default;
            }
        }

        # Localising $! means perl make make it a pretty error for us.
        local $! = $this->errno;

        return $this->_format_open_with_mode($mode, $file, $!);
    }

    # Here we must be using three arg open.

    my $file = $open_args[2];

    local $! = $this->errno;

    my $mode = $open_args[1];

    local $@;

    my $msg = eval { $this->_format_open_with_mode($mode, $file, $!); };

    return $msg if $msg;

    # Default message (for pipes and odd things)

    return "Can't open '$file' with mode '$open_args[1]': '$!'";
}

=head3 register

    autodie::exception->register( 'CORE::open' => \&mysub );

The C<register> method allows for the registration of a message
handler for a given subroutine.  The full subroutine name including
the package should be used.

Registered message handlers will receive the C<autodie::exception>
object as the first parameter.

=cut

sub register {
    my ($class, $symbol, $handler) = @_;

    croak "Incorrect call to autodie::register" if @_ != 3;

    $formatter_of{$symbol} = $handler;

}

=head3 add_file_and_line

    say "Problem occurred",$@->add_file_and_line;

Returns the string C< at %s line %d>, where C<%s> is replaced with
the filename, and C<%d> is replaced with the line number.

Primarily intended for use by format handlers.

=cut

# Simply produces the file and line number; intended to be added
# to the end of error messages.

sub add_file_and_line {
    my ($this) = @_;

    return sprintf(" at %s line %d\n", $this->file, $this->line);
}

=head3 stringify

    say "The error was: ",$@->stringify;

Formats the error as a human readable string.  Usually there's no
reason to call this directly, as it is used automatically if an
C<autodie::exception> object is ever used as a string.

Child classes can override this method to change how they're
stringified.

=cut

sub stringify {
    my ($this) = @_;

    my $call        =  $this->function;

    if ($DEBUG) {
        my $dying_pkg   = $this->package;
        my $sub   = $this->function;
        my $caller = $this->caller;
        warn "Stringifing exception for $dying_pkg :: $sub / $caller / $call\n";
    }

    # TODO - This isn't using inheritance.  Should it?
    if ( my $sub = $formatter_of{$call} ) {
        return $sub->($this) . $this->add_file_and_line;
    }

    return $this->format_default . $this->add_file_and_line;

}

=head3 format_default

    my $error_string = $E->format_default;

This produces the default error string for the given exception,
I<without using any registered message handlers>.  It is primarily
intended to be called from a message handler when they have
been passed an exception they don't want to format.

Child classes can override this method to change how default
messages are formatted.

=cut

# TODO: This produces ugly errors.  Is there any way we can
# dig around to find the actual variable names?  I know perl 5.10
# does some dark and terrible magicks to find them for undef warnings.

sub format_default {
    my ($this) = @_;

    my $call        =  $this->function;

    local $! = $this->errno;

    # TODO: This is probably a good idea for CORE, is it
    # a good idea for other subs?

    # Trim package name off dying sub for error messages.
    $call =~ s/.*:://;

    # Walk through all our arguments, and...
    #
    #   * Replace undef with the word 'undef'
    #   * Replace globs with the string '$fh'
    #   * Quote all other args.

    my @args = @{ $this->args() };

    foreach my $arg (@args) {
       if    (not defined($arg))   { $arg = 'undef' }
       elsif (ref($arg) eq "GLOB") { $arg = '$fh'   }
       else                        { $arg = qq{'$arg'} }
    }

    # Format our beautiful error.

    return "Can't $call(".  join(q{, }, @args) . "): $!" ;

    # TODO - Handle user-defined errors from hash.

    # TODO - Handle default error messages.

}

=head3 new

    my $error = autodie::exception->new(
        args => \@_,
        function => "CORE::open",
        errno => $!,
        context => 'scalar',
        return => undef,
    );


Creates a new C<autodie::exception> object.  Normally called
directly from an autodying function.  The C<function> argument
is required, its the function we were trying to call that
generated the exception.  The C<args> parameter is optional.

The C<errno> value is optional.  In versions of C<autodie::exception>
1.99 and earlier the code would try to automatically use the
current value of C<$!>, but this was unreliable and is no longer
supported.

Atrributes such as package, file, and caller are determined
automatically, and cannot be specified.

=cut

sub new {
    my ($class, @args) = @_;

    my $this = {};

    bless($this,$class);

    # I'd love to use EVERY here, but it causes our code to die
    # because it wants to stringify our objects before they're
    # initialised, causing everything to explode.

    $this->_init(@args);

    return $this;
}

sub _init {

    my ($this, %args) = @_;

    # Capturing errno here is not necessarily reliable.
    my $original_errno = $!;

    our $init_called = 1;

    my $class = ref $this;

    # We're going to walk up our call stack, looking for the
    # first thing that doesn't look like our exception
    # code, autodie/Fatal, or some whacky eval.

    my ($package, $file, $line, $sub);

    my $depth = 0;

    while (1) {
        $depth++;

        ($package, $file, $line, $sub) = CORE::caller($depth);

        # Skip up the call stack until we find something outside
        # of the Fatal/autodie/eval space.

        next if $package->isa('Fatal');
        next if $package->isa($class);
        next if $package->isa(__PACKAGE__);

        # Anything with the 'autodie::skip' role wants us to skip it.
        # https://github.com/pfenwick/autodie/issues/15

        next if ($package->can('DOES') and $package->DOES('autodie::skip'));

        next if $file =~ /^\(eval\s\d+\)$/;

        last;

    }

    # We now have everything correct, *except* for our subroutine
    # name.  If it's __ANON__ or (eval), then we need to keep on
    # digging deeper into our stack to find the real name.  However we
    # don't update our other information, since that will be correct
    # for our current exception.

    my $first_guess_subroutine = $sub;

    while (defined $sub and $sub =~ /^\(eval\)$|::__ANON__$/) {
        $depth++;

        $sub = (CORE::caller($depth))[3];
    }

    # If we end up falling out the bottom of our stack, then our
    # __ANON__ guess is the best we can get.  This includes situations
    # where we were called from the top level of a program.

    if (not defined $sub) {
        $sub = $first_guess_subroutine;
    }

    $this->{$PACKAGE}{package} = $package;
    $this->{$PACKAGE}{file}    = $file;
    $this->{$PACKAGE}{line}    = $line;
    $this->{$PACKAGE}{caller}  = $sub;
    $this->{$PACKAGE}{package} = $package;

    $this->{$PACKAGE}{errno}   = $args{errno} || 0;

    $this->{$PACKAGE}{context} = $args{context};
    $this->{$PACKAGE}{return}  = $args{return};
    $this->{$PACKAGE}{eval_error}  = $args{eval_error};

    $this->{$PACKAGE}{args}    = $args{args} || [];
    $this->{$PACKAGE}{function}= $args{function} or
              croak("$class->new() called without function arg");

    return $this;

}

1;

__END__

=head1 SEE ALSO

L<autodie>, L<autodie::exception::system>

=head1 LICENSE

Copyright (C)2008 Paul Fenwick

This is free software.  You may modify and/or redistribute this
code under the same terms as Perl 5.10 itself, or, at your option,
any later version of Perl 5.

=head1 AUTHOR

Paul Fenwick E<lt>pjf@perltraining.com.auE<gt>

Youez - 2016 - github.com/yon3zu
LinuXploit