* correct locale for that thread. Any operation that was locale-sensitive
* would have to be changed so that it would look like this:
*
- * LOCALE_LOCK;
+ * SETLOCALE_LOCK;
* setlocale to the correct locale for this operation
* do operation
- * LOCALE_UNLOCK
+ * SETLOCALE_UNLOCK
*
* This leaves the global locale in the most recently used operation's, but it
* was locked long enough to get the result. If that result is static, it
/* It might be that this is called from an already-locked section of code.
* We would have to detect and skip the LOCK/UNLOCK if so */
- LOCALE_LOCK;
+ SETLOCALE_LOCK;
curlocales[index] = savepv(my_setlocale(category, new_locale));
#endif
- LOCALE_UNLOCK;
+ SETLOCALE_UNLOCK;
return curlocales[index];
}
#if defined(HAS_NL_LANGINFO) /* nl_langinfo() is available. */
# if ! defined(HAS_THREAD_SAFE_NL_LANGINFO_L) \
- || ! defined(HAS_POSIX_2008_LOCALE) \
- || ! defined(HAS_DUPLOCALE)
+ || ! defined(HAS_POSIX_2008_LOCALE)
/* Here, use plain nl_langinfo(), switching to the underlying LC_NUMERIC
* for those items dependent on it. This must be copied to a buffer before
STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
}
- LOCALE_LOCK; /* Prevent interference from another thread executing
- this code section (the only call to nl_langinfo in
- the core) */
-
+ /* Prevent interference from another thread executing this code
+ * section. */
+ NL_LANGINFO_LOCK;
/* Copy to a per-thread buffer, which is also one that won't be
* destroyed by a subsequent setlocale(), such as the
* RESTORE_LC_NUMERIC may do just below. */
retval = save_to_buffer(nl_langinfo(item),
&PL_langinfo_buf, &PL_langinfo_bufsize, 0);
-
- LOCALE_UNLOCK;
+ NL_LANGINFO_UNLOCK;
if (toggle) {
RESTORE_LC_NUMERIC();
/* We don't bother with localeconv_l() because any system that
* has it is likely to also have nl_langinfo() */
- LOCALE_LOCK_V; /* Prevent interference with other threads
- using localeconv() */
+ LOCALECONV_LOCK; /* Prevent interference with other threads
+ using localeconv() */
# ifdef TS_W32_BROKEN_LOCALECONV
|| ! lc->currency_symbol
|| strEQ("", lc->currency_symbol))
{
- LOCALE_UNLOCK_V;
+ LOCALECONV_UNLOCK;
return "";
}
# endif
- LOCALE_UNLOCK_V;
+ LOCALECONV_UNLOCK;
break;
# ifdef TS_W32_BROKEN_LOCALECONV
STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
}
- LOCALE_LOCK_V; /* Prevent interference with other threads
- using localeconv() */
+ LOCALECONV_LOCK; /* Prevent interference with other threads
+ using localeconv() */
# ifdef TS_W32_BROKEN_LOCALECONV
# endif
- LOCALE_UNLOCK_V;
+ LOCALECONV_UNLOCK;
if (toggle) {
RESTORE_LC_NUMERIC();
case MON_5: case MON_6: case MON_7: case MON_8:
case MON_9: case MON_10: case MON_11: case MON_12:
- LOCALE_LOCK;
-
init_tm(&tm); /* Precaution against core dumps */
tm.tm_sec = 30;
tm.tm_min = 30;
tm.tm_mon = 0;
switch (item) {
default:
- LOCALE_UNLOCK;
Perl_croak(aTHX_
"panic: %s: %d: switch case: %d problem",
__FILE__, __LINE__, item);
* wday was chosen because its range is all a single digit.
* Things like tm_sec have two digits as the minimum: '00' */
- LOCALE_UNLOCK;
-
retval = PL_langinfo_buf;
/* If to return the format, not the value, overwrite the buffer
# else
- LOCALE_LOCK;
+ MBTOWC_LOCK;
PERL_UNUSED_RESULT(mbtowc(&wc, NULL, 0));/* Reset any shift state */
SETERRNO(0, 0);
len = mbtowc(&wc, STR_WITH_LEN(REPLACEMENT_CHARACTER_UTF8));
SAVE_ERRNO;
- LOCALE_UNLOCK;
+ MBTOWC_UNLOCK;
# endif
}
# elif defined(USE_POSIX_2008_LOCALE) \
- && defined(HAS_STRERROR_L) \
- && defined(HAS_DUPLOCALE)
+ && 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
* same code at the same time. (On thread-safe perls, the LOCK is a
* no-op.) Since this is the only place in core that changes LC_MESSAGES
* (unless the user has called setlocale(), this works to prevent races. */
- LOCALE_LOCK;
+ SETLOCALE_LOCK;
DEBUG_Lv(PerlIO_printf(Perl_debug_log,
"my_strerror called with errnum %d\n", errnum));
if (! within_locale_scope) {
save_locale = do_setlocale_c(LC_MESSAGES, NULL);
if (! save_locale) {
+ SETLOCALE_UNLOCK;
Perl_croak(aTHX_
"panic: %s: %d: Could not find current LC_MESSAGES locale,"
" errno=%d\n", __FILE__, __LINE__, errno);
/* The setlocale() just below likely will zap 'save_locale', so
* create a copy. */
save_locale = savepv(save_locale);
- do_setlocale_c(LC_MESSAGES, "C");
+ if (! do_setlocale_c(LC_MESSAGES, "C")) {
+
+ /* If, for some reason, the locale change failed, we
+ * soldier on as best as possible under the circumstances,
+ * using the current locale, and clear save_locale, so we
+ * don't try to change back. On z/0S, all setlocale()
+ * calls fail after you've created a thread. This is their
+ * way of making sure the entire process is always a single
+ * locale. This means that 'use locale' is always in place
+ * for messages under these circumstances. */
+ Safefree(save_locale);
+ save_locale = NULL;
+ }
}
}
} /* end of ! within_locale_scope */
if (! within_locale_scope) {
if (save_locale && ! locale_is_C) {
if (! do_setlocale_c(LC_MESSAGES, save_locale)) {
+ SETLOCALE_UNLOCK;
Perl_croak(aTHX_
- "panic: %s: %d: setlocale restore failed, errno=%d\n",
- __FILE__, __LINE__, errno);
+ "panic: %s: %d: setlocale restore to '%s' failed, errno=%d\n",
+ __FILE__, __LINE__, save_locale, errno);
}
Safefree(save_locale);
}
}
- LOCALE_UNLOCK;
+ SETLOCALE_UNLOCK;
# endif /* End of doesn't have strerror_l */
# ifdef DEBUGGING