Skip to content

Commit

Permalink
locale.c: configthreadlocale() error checking
Browse files Browse the repository at this point in the history
The code previously just assumed the system call always worked.  But it
may not if the CRTL is wrong; this surfaced on a mingw compile.

It's better to have it fail outright than to continue and silently give
a wrong answer.
  • Loading branch information
khwilliamson committed May 12, 2023
1 parent 7500b60 commit ed0527a
Showing 1 changed file with 30 additions and 11 deletions.
41 changes: 30 additions & 11 deletions locale.c
Expand Up @@ -3769,9 +3769,11 @@ S_populate_hash_from_localeconv(pTHX_ HV * hv,
const char * save_thread = querylocale_c(LC_ALL);

/* Change to the global locale, and note if we already were there */
if (_configthreadlocale(_DISABLE_PER_THREAD_LOCALE)
!= _DISABLE_PER_THREAD_LOCALE)
{
int config_return = _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
if (config_return == -1) {
locale_panic_("_configthreadlocale returned an error");
}
if (config_return != _DISABLE_PER_THREAD_LOCALE) {
restore_per_thread = TRUE;
}

Expand Down Expand Up @@ -3859,7 +3861,9 @@ S_populate_hash_from_localeconv(pTHX_ HV * hv,

/* And back to per-thread locales */
if (restore_per_thread) {
_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
if (_configthreadlocale(_ENABLE_PER_THREAD_LOCALE) == -1) {
locale_panic_("_configthreadlocale returned an error");
}
}

/* Restore the per-thread locale state */
Expand Down Expand Up @@ -5305,7 +5309,9 @@ Perl_init_i18nl10n(pTHX_ int printwarn)
# ifdef USE_THREAD_SAFE_LOCALE
# ifdef WIN32

_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
if (_configthreadlocale(_ENABLE_PER_THREAD_LOCALE) == -1) {
locale_panic_("_configthreadlocale returned an error");
}

# endif
# endif
Expand Down Expand Up @@ -7030,7 +7036,11 @@ Perl_switch_to_global_locale(pTHX)

# elif defined(WIN32)

perl_controls = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE);
int config_return = _configthreadlocale(0);
if (config_return == -1) {
locale_panic_("_configthreadlocale returned an error");
}
perl_controls = (config_return == _ENABLE_PER_THREAD_LOCALE);

# else
# error Unexpected Configuration
Expand All @@ -7046,7 +7056,9 @@ Perl_switch_to_global_locale(pTHX)
# if defined(WIN32)

const char * thread_locale = posix_setlocale(LC_ALL, NULL);
_configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
if (_configthreadlocale(_DISABLE_PER_THREAD_LOCALE) == -1) {
locale_panic_("_configthreadlocale returned an error");
}
posix_setlocale(LC_ALL, thread_locale);

# else /* Must be USE_POSIX_2008_LOCALE) */
Expand Down Expand Up @@ -7149,8 +7161,11 @@ Perl_sync_locale(pTHX)
# ifdef USE_THREAD_SAFE_LOCALE
# if defined(WIN32)

was_in_global = _configthreadlocale(_DISABLE_PER_THREAD_LOCALE)
== _DISABLE_PER_THREAD_LOCALE;
int config_return = _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
if (config_return == -1) {
locale_panic_("_configthreadlocale returned an error");
}
was_in_global = (config_return == _DISABLE_PER_THREAD_LOCALE);

# elif defined(USE_POSIX_2008_LOCALE)

Expand All @@ -7177,7 +7192,9 @@ Perl_sync_locale(pTHX)
/* On Windows, convert to per-thread behavior. This isn't necessary in
* POSIX 2008, as the conversion gets done automatically in the loop below.
* */
_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
if (_configthreadlocale(_ENABLE_PER_THREAD_LOCALE) == -1) {
locale_panic_("_configthreadlocale returned an error");
}

# endif

Expand Down Expand Up @@ -7317,7 +7334,9 @@ Perl_thread_locale_init(pTHX)
# elif defined(WIN32)

/* On Windows, make sure new thread has per-thread locales enabled */
_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
if (_configthreadlocale(_ENABLE_PER_THREAD_LOCALE) == -1) {
locale_panic_("_configthreadlocale returned an error");
}
void_setlocale_c(LC_ALL, "C");

# endif
Expand Down

0 comments on commit ed0527a

Please sign in to comment.