commit: ecfd3d86eec3e87037cd54c64b2cfc2c991742f5 Author: Kerin Millar <kfm <AT> plushkava <DOT> net> AuthorDate: Tue Oct 28 00:13:58 2025 +0000 Commit: Kerin Millar <kfm <AT> plushkava <DOT> net> CommitDate: Tue Oct 28 00:49:13 2025 +0000 URL: https://gitweb.gentoo.org/proj/locale-gen.git/commit/?id=ecfd3d86
Warn if a locale not incorporating a codeset is in effect The localedef(1) utility can be made to generate locales bearing ambiguously named aliases, such as "en_US". # locale -a en_US en_US.iso85591 These short-form aliases are bad for interoperability. Nevertheless, locale-gen(8) now explicitly supports their generation, for reasons of backward-compatibility. It stands to reason that some Gentoo users will have chosen to globally effect a locale by such an alias, though there is no way of knowing how many. At any rate, the sooner this practice can be eradicated, the better. To that end, this commit introduces the check_effective_locale() subroutine, which is called just before locale-gen(8) successfully exits. If the effective locale is found to be supported, but does not incorporate a codeset, a warning shall be issued. This warning can also be propagated by the sys-libs/glibc ebuild. # export LANG=en_US # locale-gen 2>&1 | tail -n2 WARNING! An ambiguous locale is currently in effect: en_US It is strongly recommended to choose another with eselect(1) or localectl(1). Note that eselect-1.4.31, which is currently in testing, no longer presents locales whose names do not incorporate the UTF-8 codeset, except for C and POSIX. See-also: d1d1854a402b02b23b08725dac069984506f1f96 Bug: https://bugs.gentoo.org/963974 Bug: https://bugs.gentoo.org/964713 Signed-off-by: Kerin Millar <kfm <AT> plushkava.net> locale-gen | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/locale-gen b/locale-gen index 3265b0d..3253d02 100644 --- a/locale-gen +++ b/locale-gen @@ -11,7 +11,7 @@ use Errno qw(ENOENT); use File::Spec::Functions qw(canonpath catfile catdir path splitpath); use File::Temp qw(tempdir); use Getopt::Long (); -use List::Util qw(any); +use List::Util qw(any first); use Term::ANSIColor qw(colored); # Formally stable as of v5.40; sufficiently functional in both v5.36 and v5.38. @@ -69,8 +69,11 @@ umask 0022; # Compose a list of up to two configuration files to be read. my @config_files = select_config_files($prefix, %opt); + # Compose a dictionary of supported locale/charmap combinations. + my $supported_by = map_supported_combinations($prefix); + # Collect the locales that are being requested for installation. - push @locales, read_config($prefix, @config_files); + push @locales, read_config($prefix, $supported_by, @config_files); # Compose a dictionary of installed locales for the --update option. my %installed_by; @@ -129,6 +132,9 @@ umask 0022; my $total = scalar @locales + scalar %installed_by; printf "Successfully installed an archive containing %d locale%s, of %s MiB in size.\n", $total, plural($total), round($size / 2 ** 20); + + # Issue a warning if the effective locale does not specify a charmap. + check_effective_locale($supported_by); } sub get_locale_dir () { @@ -274,9 +280,7 @@ sub normalize ($canonical) { } } -sub read_config ($prefix, @paths) { - my $supported_by = map_supported_combinations($prefix); - +sub read_config ($prefix, $supported_by, @paths) { # Iterate over the given paths and return the first non-empty list of # valid locale declarations that can be found among them, if any. for my $i (keys @paths) { @@ -586,6 +590,17 @@ sub install_archive ($src_path, $dst_path, $may_reset_labels) { } } +sub check_effective_locale ($supported_by) { + my $locale = first(sub { length $_ }, @ENV{'LC_ALL', 'LANG'}); + if (! defined $locale || $locale =~ m/\./) { + # No locale is effective, or that which is specifies a codeset. + return; + } elsif (exists $supported_by->{$locale}) { + print_warning("WARNING! An ambiguous locale is currently in effect: $locale\n"); + print_warning("It is strongly recommended to choose another with eselect(1) or localectl(1).\n"); + } +} + sub copy_security_context ($src_path, $dst_path) { local @ENV{'SRC_PATH', 'DST_PATH'} = ($src_path, $dst_path); my $stderr = qx{ LC_ALL=C chcon --reference="\$SRC_PATH" -- "\$DST_PATH" 2>&1 >/dev/null };
