Control: forwarded -1 https://rt.perl.org/Public/Bug/Display.html?id=134264
On Thu, Jul 04, 2019 at 08:04:52PM +0300, Niko Tyni wrote: > > Starting with Perl 5.28, Perl uses POSIX 2008 thread-safe locales, so > > it calls uselocale(3) underneath when the Perl side POSIX::setlocale() > > function is invoked. > > > > This makes gettext think that a translation for the new locale is already > > loaded when it really corresponds to the old locale. > > > > While this is a 5.28 regression for Perl, it's not clear to me > > whether glibc is working correctly here or not. This is now reported upstream as [perl #134264]. I'm attaching an updated test case in C, which just sets LANG at startup (as glibc won't look at LANGUAGE if the locale is totally unset / set to "C".) I'm also attaching a minimal Perl test case using Locale::gettext that demonstrates the 5.26 / 5.28 difference. -- Niko
#include <stdio.h> #include <stdlib.h> #include <libintl.h> #include <locale.h> /* https://bugs.debian.org/931139 */ int main(int argc, char **argv) { locale_t loc; int i=0; /* The C locale is special cased in glibc to not look at LANGUAGE so we set C.UTF-8 as the base locale instead */ setenv("LANG", "C.UTF-8", 1); char *locales[] = { "fi_FI", "fr_FR", "en_US", NULL }; for (i=0; locales[i] != NULL; i++) { setenv("LANGUAGE", locales[i], 1); if (argc > 1) { /* "Old" behaviour, no bug */ setlocale(LC_MESSAGES, ""); } else { /* "New" behaviour, first translation stays cached */ loc = newlocale(LC_MESSAGES_MASK, "", (locale_t) 0); if (loc == (locale_t) 0) perror("newlocale"); uselocale(loc); } printf("%s\n", dgettext("bash", "syntax error")); } return EXIT_SUCCESS; }
#!/usr/bin/perl -w use strict; use Locale::gettext; use POSIX; # The C locale is special cased in glibc to not look at LANGUAGE # so we set C.UTF-8 as the base locale instead $ENV{LANG} = 'C.UTF-8'; for my $lang (qw(fi_FI fr_FR en_US)) { $ENV{LANGUAGE} = $lang; setlocale(LC_MESSAGES, ''); my $d = Locale::gettext->domain("bash"); print $d->get('syntax error'), "\n"; }