bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

hard-locale: make multithread-safe


From: Bruno Haible
Subject: hard-locale: make multithread-safe
Date: Tue, 17 Dec 2019 14:45:09 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-166-generic; KDE/5.18.0; x86_64; ; )

Hi Paul,

Here is a proposed patch to make the hard_locale() function multithread-safe.
This is needed because our mbrtowc() override relies on hard_locale, and
mbrtowc obviously must be multi-thread safe (that's one of its main features,
compared to mbtowc).

The previous hard_locale code tries to guess whether a locale is in fact
a "C"/"POSIX" locale, although it is not apparent from its name. This was
a case to worry about between 1995 and 2000, when many systems did not
have working locales. This has changed: Nowadays nearly all platforms
honour the locale names with some localized behaviour, except OpenBSD,
Minix, and Android. It's not my priority to optimize for these three
systems. But if you want to keep optimizations for these platforms,
we could add #ifs for these platforms.


2019-12-17  Bruno Haible  <address@hidden>

        hard-locale: Make multithread-safe.
        * lib/hard-locale.h (hard_locale): Move documentation to here.
        * lib/hard-locale.c: Don't include <stdlib.h>.
        (GLIBC_VERSION): Remove macro.
        (hard_locale): Assume that all systems name the "C" and "POSIX" locales
        "C" or "POSIX". Invoke setlocale_null instead of setlocale.
        * modules/hard-locale (Depends-on): Remove strdup. Add setlocale-null.

diff --git a/lib/hard-locale.h b/lib/hard-locale.h
index 8f1da96..160674b 100644
--- a/lib/hard-locale.h
+++ b/lib/hard-locale.h
@@ -20,6 +20,9 @@
 
 # include <stdbool.h>
 
-bool hard_locale (int);
+/* Return true if the specified CATEGORY of the current locale is hard, i.e.
+   different from the C or POSIX locale that has a fixed behavior.
+   CATEGORY must be one of the LC_* values, but not LC_ALL.  */
+extern bool hard_locale (int category);
 
 #endif /* HARD_LOCALE_H_ */diff --git a/lib/hard-locale.c b/lib/hard-locale.c
index dcfcad6..4a2adab 100644
--- a/lib/hard-locale.c
+++ b/lib/hard-locale.c
@@ -21,52 +21,15 @@
 #include "hard-locale.h"
 
 #include <locale.h>
-#include <stdlib.h>
 #include <string.h>
 
-#ifdef __GLIBC__
-# define GLIBC_VERSION __GLIBC__
-#elif defined __UCLIBC__
-# define GLIBC_VERSION 2
-#else
-# define GLIBC_VERSION 0
-#endif
-
-/* Return true if the current CATEGORY locale is hard, i.e. if you
-   can't get away with assuming traditional C or POSIX behavior.  */
 bool
 hard_locale (int category)
 {
-  bool hard = true;
-  char const *p = setlocale (category, NULL);
-
-  if (p)
-    {
-      if (2 <= GLIBC_VERSION)
-        {
-          if (strcmp (p, "C") == 0 || strcmp (p, "POSIX") == 0)
-            hard = false;
-        }
-      else
-        {
-          char *locale = strdup (p);
-          if (locale)
-            {
-              /* Temporarily set the locale to the "C" and "POSIX" locales
-                 to find their names, so that we can determine whether one
-                 or the other is the caller's locale.  */
-              if (((p = setlocale (category, "C"))
-                   && strcmp (p, locale) == 0)
-                  || ((p = setlocale (category, "POSIX"))
-                      && strcmp (p, locale) == 0))
-                hard = false;
+  char locale[SETLOCALE_NULL_MAX];
 
-              /* Restore the caller's locale.  */
-              setlocale (category, locale);
-              free (locale);
-            }
-        }
-    }
+  if (setlocale_null (category, locale, sizeof (locale)))
+    return false;
 
-  return hard;
+  return !(strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0);
 }

diff --git a/modules/hard-locale b/modules/hard-locale
index d4463b7..02be90a 100644
--- a/modules/hard-locale
+++ b/modules/hard-locale
@@ -7,7 +7,7 @@ lib/hard-locale.c
 
 Depends-on:
 stdbool
-strdup
+setlocale-null
 
 configure.ac:
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]