diff options
-rw-r--r-- | locale.c | 36 | ||||
-rw-r--r-- | makedef.pl | 1 | ||||
-rw-r--r-- | perl.c | 2 | ||||
-rw-r--r-- | perl.h | 4 | ||||
-rw-r--r-- | perlvars.h | 6 |
5 files changed, 28 insertions, 21 deletions
@@ -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 ); } @@ -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 @@ -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 |