vsespb has asked for the wisdom of the Perl Monks concerning the following question:

Recently I found that ERRNO ( "$!" or POSIX::strerror($!+0) ) is actually locale-dependant.

perllocale:
Note especially that the string value of $! and the error messages given by external utilities may be changed by LC_MESSAGES . If you want to have portable error codes, use %! . See Errno.
Example: the following commands print different binary strings. First prints "File not found" message translated to Russian in WINDOWS-1251, second in UTF-8:
LANG=ru_RU LANGUAGE=ru_RU:ru LC_ALL=ru_RU.CP1251 LC_MESSAGES=ru_RU.CP1 +251 perl -e 'open my $f, "<", "notafile" or print $!'
LANG=ru_RU LANGUAGE=ru_RU:ru LC_ALL=ru_RU.utf8 perl -e 'open my $f, " +<", "notafile" or print $!'
I would like to convert binary strings to character strings (and print it on the screen in the end with other information):
my $errno = decode("SOMEENCODING", $!)
Problem is: what is the most convenient and reliable way to determine $! encoding?

The is 'use locale', but seems it's obsolete way to work with single byte-encoding and binary strings, and it's not a good idea to mix it with Unicode.

Note that I have already binmode STDOUT, ":encoding(UTF-8)" and option for user to override terminal encoding, and that works fine. However it won't work with $! for me, because I have a testsuite which tests my error handling code and testsuite can be ran on different locales without way to specify encoding. Obviously decode("UTF-8, $!) can break if encoding is wrong (not every byte sequence is correct character sequence in UTF-8 encoding).

Replies are listed 'Best First'.
Re: locale and errno
by daxim (Curate) on Aug 27, 2013 at 15:04 UTC
      Yes, indeed, thanks! I was surprised that I18N::Langinfo is core module!

      Also I found now Encode::Locale, which is not core module, but seems it makes sure I18N::Langinfo output is compatible with Encode module (and does some additional work related to FS encoding + encodings on Win32)