Errno-AnyString

 view release on metacpan or  search on metacpan

lib/Errno/AnyString.pm  view on Meta::CPAN


  # ...

  $! = -20001;
  print "$!\n"; # prints Invalid foodb parameter

It is also possible to use register_errstr() to replace the standard system error messages. For example, to replace the "Permission denied" message;

  use Errno qw/EACCES/;
  register_errstr "I'm sorry, Dave. I'm afraid I can't do that", EACCES;

  open my $fh, ">/no_permission_to_write_here";
  print "$!\n"; prints "I'm sorry, Dave. I'm afraid I can't do that"

This is not something I'd recommend, as it's likely to cause confusion. In general, when specifying the C<errno> value to register_errstr() one should take care to avoid values that are likely to be used for any other purpose.

Internally, the error strings registered by register_errstr() are kept in the C<%Errno::AnyString::Errno2Errstr> hash. You shouldn't go poking around in this hash yourself, but by localising it you can limit the scope of a register_errstr() registrat...
  
  {
      local %Errno::AnyString::Errno2Errstr = %Errno::AnyString::Errno2Errstr;

      register_errstr "I'm sorry, Dave. I'm afraid I can't do that", EACCES;

      # here you have a silly error message in place of "Permission denied"
  }
  # here sanity is restored

=cut

sub register_errstr ($;$) {
    my ($str, $num) = @_;

    tainted $str and croak "Tainted error string used with Errno::AnyString";

    unless (defined $num) {
        $num = $_string2errno{$str};
        unless (defined $num) {
            $num = $_next_registered_errno++;
            $_string2errno{$str} = $num;
        }
    }
    $Errno2Errstr{$num} = "$str";

    return dualvar $num, $str;
}

=head1 INTER-OPERATION

This section is aimed at the authors of other modules that alter C<$!>'s behaviour, as a guide to ensuring clean inter-operation between Errno::AnyString and your module.

Errno::AnyString works by adding two instances of uvar magic to C<$!>, one at the head of the list and one at the tail. It does not modify or remove any existing magic from C<$!>. It should inter-operate cleanly with anything else that adds more magi...

Emptying the C<%Errno::AnyString::Errno2Errstr> hash effectively turns off this module's interference with C<$!>, so you can get a "real" C<$!> value with:

  my $e = do { local %Errno::AnyString::Errno2Errstr ; $! };

=head1 AUTHOR

Dave Taylor, C<< <dave.taylor.cpan at gmail.com> >>

=head1 BUGS AND LIMITATIONS

=head2 C LEVEL STRERROR CALLS

If C level code attempts to get a textual error message based on C<errno> while a custom error string is set, it will get something like the following, depending on the platform:

  Unknown error 458513437

=head2 PURE NUMERIC RESTORE

If the string part of a saved custom_errstr() C<$!> value is lost, then restoring that value to C<$!> restores the string most recently set with custom_errstr(), which is not necessarily the string that was set when the C<$!> value was saved.

  $! = custom_errstr "String 1";
  my $saved_errno = 0 + $!;

  $! = custom_errstr "String 2";

  $! = $saved_errno;
  print "$!\n"; # prints String 2

Note that the Perl code that saved the error number had to go out of its way to discard the string part of C<$!>, so I think this combination is fairly unlikely in practice.

Error strings set with register_errstr() are not effected by this issue, since each gets its own unique C<errno> value. For this reason, register_errstr() should be used in preference to custom_errstr() if you have a small number of fixed error strin...

  $! = register_errstr "Attempt to frob without a foo"; # good

However, register_errstr() uses up an C<errno> value and permanently stores the string each time it is called with a string it has not seen before. If your code could generate a large number of different error strings over the lifetime of the Perl in...

  $! = register_errstr "failed at $line in $file: $why"; # less good 

=head2 TAINT MODE

I'm currently unable to find a good way to propagate the taintedness of custom error strings through C<$!>, due to an interaction between taint magic, C<$!>'s dualvar behaviour and the SvPOK flag in some Perl versions. If Perl is in taint mode then p...

  Tainted error string used with Errno::AnyString

=head2 OTHER BUGS

Please report any other bugs or feature requests to C<bug-errno-anystring at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Errno::AnyString>.  I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Errno::AnyString

You can also look for information at:

=over 4

=item * RT: CPAN's request tracker

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Errno::AnyString>

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/Errno::AnyString>

=item * CPAN Ratings



( run in 0.962 second using v1.01-cache-2.11-cpan-39bf76dae61 )