Skip to content

Commit

Permalink
locale.c: Separate setlocale into bool and query
Browse files Browse the repository at this point in the history
There are two ways that POSIX specifies to change the locale.

The earlier interface is setlocale(), which either returns NULL on
failure, or a pointer to global static memory containing the character
string of the changed locale.  That may very well be the input locale
name, or the platform can return something that to it is equivalent.

The second, from the 2008 standard, is newlocale() which returns either
NULL on failure or a pointer to an opaque object, and there is no
official way to find out what the current locale is.  (The next proposed
version of the Standard will finally add this capability.)  Some
platforms have introduced a querylocale() to get this information.
(glibc has a hidden function to do so.)

Note that the return value of setlocale() is problematic, valid only
until the next call to that function, which might be immediately from
another thread.  The value, if needed, has to be saved to a per-thread
buffer in a critical section with the function call.  That buffer
presents opportunities for leaking or being destroyed too early,
resulting in heap use after being freed.

And it turns out that the value is often not needed; often what is
needed is only if the operation failed or succeeded.

This commit starts the process of limiting the use of the changed value
to just where its really needed.  It does this by changing the
newlocale() form to return success/failure, removing all the macros that
think you can set and get the value in the same operation, and minor
fixups.
  • Loading branch information
khwilliamson committed May 6, 2023
1 parent b9d4dd4 commit 8514fce
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 113 deletions.
12 changes: 5 additions & 7 deletions embed.fnc
Expand Up @@ -4407,9 +4407,9 @@ S |void |new_numeric |NN const char *newnum \
S |const char *|get_LC_ALL_display
# endif
# if defined(USE_POSIX_2008_LOCALE)
S |const char *|emulate_setlocale_i \
S |bool |bool_setlocale_2008_i \
|const unsigned int index \
|NULLOK const char *new_locale \
|NN const char *new_locale \
|const recalc_lc_all_t recalc_LC_ALL \
|const line_t line
S |const char *|querylocale_2008_i \
Expand All @@ -4431,6 +4431,9 @@ S |const char *|update_PL_curlocales_i \
!defined(USE_THREAD_SAFE_LOCALE) && \
!defined(USE_THREAD_SAFE_LOCALE_EMULATION) /* &&
!defined(USE_POSIX_2008_LOCALE) */
S |bool |less_dicey_bool_setlocale_r \
|const int cat \
|NN const char *locale
S |const char *|less_dicey_setlocale_r \
|const int category \
|NULLOK const char *locale
Expand All @@ -4439,11 +4442,6 @@ S |void |less_dicey_void_setlocale_i \
|const unsigned cat_index \
|NN const char *locale \
|const line_t line
# if 0
S |bool |less_dicey_bool_setlocale_r \
|const int cat \
|NN const char *locale
# endif
# endif
# if !( defined(USE_POSIX_2008_LOCALE) && defined(USE_QUERYLOCALE) ) && \
( !defined(LC_ALL) || defined(USE_POSIX_2008_LOCALE) || \
Expand Down
6 changes: 2 additions & 4 deletions embed.h
Expand Up @@ -1300,7 +1300,7 @@
# define get_LC_ALL_display() S_get_LC_ALL_display(aTHX)
# endif
# if defined(USE_POSIX_2008_LOCALE)
# define emulate_setlocale_i(a,b,c,d) S_emulate_setlocale_i(aTHX_ a,b,c,d)
# define bool_setlocale_2008_i(a,b,c,d) S_bool_setlocale_2008_i(aTHX_ a,b,c,d)
# define querylocale_2008_i(a) S_querylocale_2008_i(aTHX_ a)
# define setlocale_from_aggregate_LC_ALL(a,b) S_setlocale_from_aggregate_LC_ALL(aTHX_ a,b)
# define use_curlocale_scratch() S_use_curlocale_scratch(aTHX)
Expand All @@ -1313,11 +1313,9 @@
!defined(USE_THREAD_SAFE_LOCALE) && \
!defined(USE_THREAD_SAFE_LOCALE_EMULATION) /* &&
!defined(USE_POSIX_2008_LOCALE) */
# define less_dicey_bool_setlocale_r(a,b) S_less_dicey_bool_setlocale_r(aTHX_ a,b)
# define less_dicey_setlocale_r(a,b) S_less_dicey_setlocale_r(aTHX_ a,b)
# define less_dicey_void_setlocale_i(a,b,c) S_less_dicey_void_setlocale_i(aTHX_ a,b,c)
# if 0
# define less_dicey_bool_setlocale_r(a,b) S_less_dicey_bool_setlocale_r(aTHX_ a,b)
# endif
# endif
# if !( defined(USE_POSIX_2008_LOCALE) && defined(USE_QUERYLOCALE) ) && \
( !defined(LC_ALL) || defined(USE_POSIX_2008_LOCALE) || \
Expand Down

0 comments on commit 8514fce

Please sign in to comment.