From 737d158210afaf95c84f66b6037b44cd00d512b9 Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Sat, 3 Sep 2022 14:49:52 -0600 Subject: [PATCH] locale.c: Don't ever use system LC_ALL This fixes #20231 LC_ALL is a compendium of the individual locale categories, such as LC_CTYPE, LC_NUMERIC, .... When all categories are in the same locale, it acts just like an individual category. But when the categories are not in the same locale, some means must be used to indicate that. Platforms differ in how they represent this. Alpine uses: a;b;c;d;e;f where each letter is replaced by the correct locale for a given category. Which category is in which position is deterministic, and platform-specific. Other platforms separate by a '/'. And glibc uses a more informative format: LC_CTYPE=a;LC_NUMBERIC=b; ... This has the advantage that it's obvious to the reader what is what, and the order in the string is irrelevant. It might be possible, but painful, for a Configure probe to figure out what the syntax is for the current platform. I chose not to do that. A platform might come along with a novel syntax unanticipated by whatever probe we came up with. Instead, perl uses the glibc format internally, and when it needs to get or set LC_ALL from the system, it loops through each category individually, so that by the time it has done all of them, LC_ALL will have been implicitly handled. The breaking commit a7ff7ac failed to do that. --- locale.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/locale.c b/locale.c index 576db7dddfbb..f1856ca05db4 100644 --- a/locale.c +++ b/locale.c @@ -4649,8 +4649,12 @@ Perl_init_i18nl10n(pTHX_ int printwarn) # endif # ifdef USE_PL_CURLOCALES - /* Initialize our records. If we have POSIX 2008, we have LC_ALL */ - void_setlocale_c(LC_ALL, porcelain_setlocale(LC_ALL, NULL)); + /* Initialize our records. */ + for (i = 0; i < NOMINAL_LC_ALL_INDEX; i++) { + (void) emulate_setlocale_i(i, porcelain_setlocale(categories[i], NULL), + RECALCULATE_LC_ALL_ON_FINAL_INTERATION, + __LINE__); + } # endif