* `$SYSTEMD_KEYMAP_DIRECTORIES=` — takes a colon (`:`) separated list of keymap
directories. The directories must be absolute and normalized. If unset, the
- default keymap directories (/usr/share/keymaps/, /usr/share/kbd/keymaps/, and
- /usr/lib/kbd/keymaps/) will be used.
+ default keymap directories (`/usr/share/keymaps/`, `/usr/share/kbd/keymaps/`,
+ and `/usr/lib/kbd/keymaps/`) will be used.
-* `$SYSTEMD_XKB_DIRECTORY=` — The directory must be absolute and normalized.
- If unset, the default XKB directory (/usr/share/X11/xkb) will be used.
+* `$SYSTEMD_XKB_DIRECTORY=` — The directory must be absolute and normalized. If
+ unset, the default XKB directory (`/usr/share/X11/xkb/`) will be used.
+
+* `$SYSTEMD_LOCALE_DIRECTORY=` — The directory must be absolute and normalized.
+ If unset, the default locale directory of the C library (`/usr/lib/locale/`
+ for glibc and `/usr/share/i18n/locales/musl/` for musl) will be used.
`systemd-resolved`:
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
+}
+
#ifdef __GLIBC__
static int add_locales_from_archive(Set *locales) {
/* Stolen from glibc... */
assert(locales);
- _cleanup_close_ int fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC);
+ _cleanup_free_ char *locale_archive_file = path_join(get_locale_dir(), "locale-archive");
+ if (!locale_archive_file)
+ return -ENOMEM;
+
+ _cleanup_close_ int fd = open(locale_archive_file, O_RDONLY|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
return errno == ENOENT ? 0 : -errno;
assert(locales);
- dir = opendir("/usr/lib/locale");
+ dir = opendir(get_locale_dir());
if (!dir)
return errno == ENOENT ? 0 : -errno;
assert(locales);
- _cleanup_closedir_ DIR *dir = opendir("/usr/share/i18n/locales/musl/");
+ _cleanup_closedir_ DIR *dir = opendir(get_locale_dir());
if (!dir)
return errno == ENOENT ? 0 : -errno;
/* 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("/usr/share/i18n/locales/musl/", name);
+ _cleanup_free_ char *p = path_join(get_locale_dir(), name);
if (!p)
return -ENOMEM;