summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--locale.c36
-rw-r--r--makedef.pl1
-rw-r--r--perl.c2
-rw-r--r--perl.h4
-rw-r--r--perlvars.h6
5 files changed, 28 insertions, 21 deletions
diff --git a/locale.c b/locale.c
index 277e038327..e58fb3b5f2 100644
--- a/locale.c
+++ b/locale.c
@@ -3110,7 +3110,7 @@ Perl_init_i18nl10n(pTHX_ int printwarn)
# endif
# endif
-# if defined(LC_ALL_MASK) && defined(HAS_POSIX_2008_LOCALE)
+# ifdef USE_POSIX_2008_LOCALE
PL_C_locale_obj = newlocale(LC_ALL_MASK, "C", (locale_t) 0);
if (! PL_C_locale_obj) {
@@ -4875,19 +4875,31 @@ Perl_my_strerror(pTHX_ const int errnum)
const bool within_locale_scope = IN_LC(LC_MESSAGES);
-# if defined(HAS_POSIX_2008_LOCALE) && defined(HAS_STRERROR_L)
+# ifndef USE_ITHREADS
- /* This function is trivial if we don't have to worry about thread safety
- * and have strerror_l(), as it handles the switch of locales so we don't
- * have to deal with that. We don't have to worry about thread safety if
- * this is an unthreaded build, or if strerror_r() is also available. Both
- * it and strerror_l() are thread-safe. Plain strerror() isn't thread
- * safe. But on threaded builds when strerror_r() is available, the
- * apparent call to strerror() below is actually a macro that
- * behind-the-scenes calls strerror_r().
- */
+ /* This function is trivial without threads. */
+ if (within_locale_scope) {
+ errstr = savepv(strerror(errnum));
+ }
+ else {
+ const char * save_locale = do_setlocale_c(LC_MESSAGES, NULL);
+
+ do_setlocale_c(LC_MESSAGES, "C");
+ errstr = savepv(strerror(errnum));
+ do_setlocale_c(LC_MESSAGES, save_locale);
+ }
+
+# elif defined(HAS_POSIX_2008_LOCALE) && defined(HAS_STRERROR_L)
+
+ /* This function is also trivial if we don't have to worry about thread
+ * safety and have strerror_l(), as it handles the switch of locales so we
+ * don't have to deal with that. We don't have to worry about thread
+ * safety if strerror_r() is also available. Both it and strerror_l() are
+ * thread-safe. Plain strerror() isn't thread safe. But on threaded
+ * builds when strerror_r() is available, the apparent call to strerror()
+ * below is actually a macro that behind-the-scenes calls strerror_r(). */
-# if ! defined(USE_ITHREADS) || defined(HAS_STRERROR_R)
+# ifdef HAS_STRERROR_R
if (within_locale_scope) {
errstr = savepv(strerror(errnum));
diff --git a/makedef.pl b/makedef.pl
index 626d990744..f2b4684ee1 100644
--- a/makedef.pl
+++ b/makedef.pl
@@ -398,6 +398,7 @@ unless ($define{'USE_ITHREADS'}) {
Perl_stashpv_hvname_match
Perl_regdupe_internal
Perl_newPADOP
+ PL_C_locale_obj
);
}
diff --git a/perl.c b/perl.c
index 1bc15a0675..f894780a0b 100644
--- a/perl.c
+++ b/perl.c
@@ -470,7 +470,7 @@ perl_construct(pTHXx)
/* Start with 1 bucket, for DFS. It's unlikely we'll need more. */
HvMAX(PL_registered_mros) = 0;
-#ifdef HAS_POSIX_2008_LOCALE
+#ifdef USE_POSIX_2008_LOCALE
PL_C_locale_obj = newlocale(LC_ALL_MASK, "C", NULL);
#endif
diff --git a/perl.h b/perl.h
index dd81d6246b..3a8a29f08a 100644
--- a/perl.h
+++ b/perl.h
@@ -5643,9 +5643,7 @@ typedef struct am_table_short AMTS;
#endif
#ifdef USE_LOCALE /* These locale things are all subject to change */
- /* We create a C locale object unconditionally if we have the functions to
- * do so; hence must destroy it unconditionally at the end */
-# ifndef HAS_POSIX_2008_LOCALE
+# ifndef USE_POSIX_2008_LOCALE
# define _LOCALE_TERM_POSIX_2008 NOOP
# else
# define _LOCALE_TERM_POSIX_2008 \
diff --git a/perlvars.h b/perlvars.h
index 0f2e3475d3..d3275835dc 100644
--- a/perlvars.h
+++ b/perlvars.h
@@ -105,11 +105,7 @@ PERLVAR(G, lc_numeric_mutex, perl_mutex) /* Mutex for switching LC_NUMERIC */
# endif
#endif
-/* Proxy for HAS_POSIX_2008_LOCALE, since that is not defined in time for this */
-#if defined(HAS_NEWLOCALE) \
- && defined(HAS_FREELOCALE) \
- && defined(HAS_USELOCALE) \
- && ! defined(NO_POSIX_2008_LOCALE)
+#ifdef USE_POSIX_2008_LOCALE
PERLVAR(G, C_locale_obj, locale_t)
#endif