]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
locale-util: modernize is_locale_utf8() a bit
authorMike Yuan <me@yhndnzj.com>
Tue, 4 Mar 2025 17:42:24 +0000 (18:42 +0100)
committerMike Yuan <me@yhndnzj.com>
Tue, 4 Mar 2025 22:03:23 +0000 (23:03 +0100)
src/basic/locale-util.c

index 09bdb373007a3f3a873611ef48555c7d6e91b02a..c7095ece2397765ba0f5cf9f80f2e92341d1a2ab 100644 (file)
@@ -17,8 +17,8 @@
 #include "fileio.h"
 #include "hashmap.h"
 #include "locale-util.h"
-#include "missing_syscall.h"
 #include "path-util.h"
+#include "process-util.h"
 #include "set.h"
 #include "string-table.h"
 #include "string-util.h"
@@ -283,64 +283,48 @@ int locale_is_installed(const char *name) {
         return true;
 }
 
-bool is_locale_utf8(void) {
-        static int cached_answer = -1;
+static bool is_locale_utf8_impl(void) {
         const char *set;
         int r;
 
-        /* Note that we default to 'true' here, since today UTF8 is
-         * pretty much supported everywhere. */
-
-        if (cached_answer >= 0)
-                goto out;
+        /* Note that we default to 'true' here, since today UTF8 is pretty much supported everywhere. */
 
         r = secure_getenv_bool("SYSTEMD_UTF8");
-        if (r >= 0) {
-                cached_answer = r;
-                goto out;
-        } else if (r != -ENXIO)
+        if (r >= 0)
+                return r;
+        if (r != -ENXIO)
                 log_debug_errno(r, "Failed to parse $SYSTEMD_UTF8, ignoring: %m");
 
         /* This function may be called from libsystemd, and setlocale() is not thread safe. Assuming yes. */
-        if (gettid() != raw_getpid()) {
-                cached_answer = true;
-                goto out;
-        }
+        if (!is_main_thread())
+                return true;
 
-        if (!setlocale(LC_ALL, "")) {
-                cached_answer = true;
-                goto out;
-        }
+        if (!setlocale(LC_ALL, ""))
+                return true;
 
         set = nl_langinfo(CODESET);
-        if (!set) {
-                cached_answer = true;
-                goto out;
-        }
-
-        if (streq(set, "UTF-8")) {
-                cached_answer = true;
-                goto out;
-        }
+        if (!set || streq(set, "UTF-8"))
+                return true;
 
-        /* For LC_CTYPE=="C" return true, because CTYPE is effectively
-         * unset and everything can do to UTF-8 nowadays. */
         set = setlocale(LC_CTYPE, NULL);
-        if (!set) {
-                cached_answer = true;
-                goto out;
-        }
+        if (!set)
+                return true;
 
-        /* Check result, but ignore the result if C was set
-         * explicitly. */
-        cached_answer =
-                STR_IN_SET(set, "C", "POSIX") &&
+        /* Unless LC_CTYPE is explicitly overridden, return true. Because here CTYPE is effectively unset
+         * and everything can do to UTF-8 nowadays. */
+        return STR_IN_SET(set, "C", "POSIX") &&
                 !getenv("LC_ALL") &&
                 !getenv("LC_CTYPE") &&
                 !getenv("LANG");
+}
+
+bool is_locale_utf8(void) {
+        static int cached = -1;
+
+        if (cached < 0)
+                cached = is_locale_utf8_impl();
 
-out:
-        return (bool) cached_answer;
+        return cached;
 }
 
 void locale_variables_free(char *l[_VARIABLE_LC_MAX]) {