]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
locale-util: allow overriding locale directory via environment
authorandre4ik3 <andre4ik3@fastmail.com>
Wed, 11 Feb 2026 07:04:00 +0000 (07:04 +0000)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 15 Feb 2026 23:09:33 +0000 (08:09 +0900)
docs/ENVIRONMENT.md
src/basic/locale-util.c

index 2de688eb5df53777e2cbc9f52a33954d284cf41d..5390754661879ed314d7dc3a104939fe6469533e 100644 (file)
@@ -382,11 +382,15 @@ All tools:
 
 * `$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`:
 
index 6e752994185bfbe3eeb85cc3e7f5210c5e087e00..11e91ab8345051c639adacabed1a2d4236fd02ce 100644 (file)
@@ -55,6 +55,15 @@ 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
+}
+
 #ifdef __GLIBC__
 static int add_locales_from_archive(Set *locales) {
         /* Stolen from glibc... */
@@ -94,7 +103,11 @@ static int add_locales_from_archive(Set *locales) {
 
         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;
 
@@ -162,7 +175,7 @@ static int add_locales_from_libdir(Set *locales) {
 
         assert(locales);
 
-        dir = opendir("/usr/lib/locale");
+        dir = opendir(get_locale_dir());
         if (!dir)
                 return errno == ENOENT ? 0 : -errno;
 
@@ -191,7 +204,7 @@ static int add_locales_for_musl(Set *locales) {
 
         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;
 
@@ -313,7 +326,7 @@ 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("/usr/share/i18n/locales/musl/", name);
+        _cleanup_free_ char *p = path_join(get_locale_dir(), name);
         if (!p)
                 return -ENOMEM;