locale-util: Update musl's default locale search paths
musl libc got a overhaul in it's locale support funded by NLnet, as part the default search paths were set to search in /etc/musl/locale, /usr/share/musl/locale, /share/musl/locale/. Also change the behaviour on musl to search for multiple directories, and include the old path as a fallback. See https://www.openwall.com/lists/musl/2026/10/02/1 (cherry picked from commit 0f655ffc7b3318abae41869ca192e1817586a985)
This commit is contained in:
committed by
Luca Boccassi
parent
3e39c54632
commit
934e31fac0
+36
-22
@@ -56,16 +56,11 @@ static char* normalize_locale(const char *name) {
|
||||
return strdup(name);
|
||||
}
|
||||
|
||||
static const char* get_locale_dir(void) {
|
||||
return secure_getenv("SYSTEMD_LOCALE_DIRECTORY") ?:
|
||||
#ifdef __GLIBC__
|
||||
"/usr/lib/locale/";
|
||||
#else
|
||||
"/usr/share/i18n/locales/musl/";
|
||||
#endif
|
||||
static const char* get_locale_dir(void) {
|
||||
return secure_getenv("SYSTEMD_LOCALE_DIRECTORY") ?: "/usr/lib/locale/";
|
||||
}
|
||||
|
||||
#ifdef __GLIBC__
|
||||
static int add_locales_from_archive(Set *locales) {
|
||||
/* Stolen from glibc... */
|
||||
|
||||
@@ -201,26 +196,38 @@ static int add_locales_from_libdir(Set *locales) {
|
||||
|
||||
#else
|
||||
|
||||
static const char* const musl_locale_dirs[] = {
|
||||
"/etc/musl/locale",
|
||||
"/usr/share/musl/locale",
|
||||
"/share/musl/locale",
|
||||
"/usr/share/i18n/locales/musl", // compat with musl-locales 0.1.0
|
||||
NULL
|
||||
};
|
||||
|
||||
static int add_locales_for_musl(Set *locales) {
|
||||
int r;
|
||||
|
||||
assert(locales);
|
||||
|
||||
_cleanup_closedir_ DIR *dir = opendir(get_locale_dir());
|
||||
if (!dir)
|
||||
return errno == ENOENT ? 0 : -errno;
|
||||
const char *e = secure_getenv("SYSTEMD_LOCALE_DIRECTORY");
|
||||
|
||||
FOREACH_DIRENT(de, dir, return -errno) {
|
||||
if (de->d_type != DT_REG)
|
||||
STRV_FOREACH(d, e ? STRV_MAKE_CONST(e) : musl_locale_dirs) {
|
||||
_cleanup_closedir_ DIR *dir = opendir(*d);
|
||||
if (!dir)
|
||||
continue;
|
||||
|
||||
char *z = normalize_locale(de->d_name);
|
||||
if (!z)
|
||||
return -ENOMEM;
|
||||
FOREACH_DIRENT(de, dir, return -errno) {
|
||||
if (de->d_type != DT_REG)
|
||||
continue;
|
||||
|
||||
r = set_consume(locales, z);
|
||||
if (r < 0)
|
||||
return r;
|
||||
char *z = normalize_locale(de->d_name);
|
||||
if (!z)
|
||||
return -ENOMEM;
|
||||
|
||||
r = set_consume(locales, z);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -330,11 +337,18 @@ int locale_is_installed(const char *name) {
|
||||
|
||||
/* musl's newlocale() always succeeds and provides a fake locale object even when the locale does
|
||||
* not exist. Hence, we need to explicitly check if the locale file exists. */
|
||||
_cleanup_free_ char *p = path_join(get_locale_dir(), name);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
const char *e = secure_getenv("SYSTEMD_LOCALE_DIRECTORY");
|
||||
|
||||
return access(p, F_OK) >= 0;
|
||||
STRV_FOREACH(d, e ? STRV_MAKE_CONST(e) : musl_locale_dirs) {
|
||||
_cleanup_free_ char *p = path_join(*d, name);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
if (access(p, F_OK) >= 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user