From: Mike Yuan Date: Tue, 4 Mar 2025 17:42:24 +0000 (+0100) Subject: locale-util: modernize is_locale_utf8() a bit X-Git-Tag: v258-rc1~1185^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c133fcd5c0ebaf72bfea12f165c3b727a0fb5ffb;p=thirdparty%2Fsystemd.git locale-util: modernize is_locale_utf8() a bit --- diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c index 09bdb373007..c7095ece239 100644 --- a/src/basic/locale-util.c +++ b/src/basic/locale-util.c @@ -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]) {