From a0fe984953ddaa808a00612b5c6959d1c3987a2d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 24 Mar 2025 21:28:02 +0100 Subject: getlocalename_l: allow LC_ALL category Following the changes from Austin Group bug https://www.austingroupbugs.net/view.php?id=1741, getlocalename_l() now allows to specify LC_ALL and returns a setlocale-conmpatible LC_ALL locale string. Consequentially we have to raise the size of _reent::_getlocalename_l_buf so there's enough space for the LC_ALL locale string. Guard all different definitions and usages of _getlocalename_l_buf in reent.h with _MB_CAPABLE. Link: https://www.austingroupbugs.net/view.php?id=1741 Fixes: 71511d4ac868 ("getlocalename_l: implement per SUS Base Specifications Issue 8 draft") Signed-off-by: Corinna Vinschen --- newlib/libc/include/sys/reent.h | 11 +++++++++-- newlib/libc/locale/getlocalename_l.c | 9 ++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'newlib/libc') diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h index 0cba166..5ce5387 100644 --- a/newlib/libc/include/sys/reent.h +++ b/newlib/libc/include/sys/reent.h @@ -370,7 +370,7 @@ struct _misc_reent _mbstate_t _wcrtomb_state; _mbstate_t _wcsrtombs_state; #ifdef _MB_CAPABLE - char _getlocalename_l_buf[32 /*ENCODING + 1*/]; + char _getlocalename_l_buf[7 /* _LC_LAST */ * 32 /*ENCODING + 1*/]; #endif }; @@ -570,7 +570,9 @@ struct _reent #define _REENT_WCSRTOMBS_STATE(ptr) ((ptr)->_misc->_wcsrtombs_state) #define _REENT_L64A_BUF(ptr) ((ptr)->_misc->_l64a_buf) #define _REENT_GETDATE_ERR_P(ptr) (&((ptr)->_misc->_getdate_err)) +#ifdef _MB_CAPABLE #define _REENT_GETLOCALENAME_L_BUF(ptr) ((ptr)->_misc->_getlocalename_l_buf) +#endif #define _REENT_SIGNAL_BUF(ptr) ((ptr)->_signal_buf) #else /* !_REENT_SMALL */ @@ -641,10 +643,13 @@ struct _reent _mbstate_t _mbrtoc16_state; _mbstate_t _mbrtoc32_state; #endif +#ifdef _MB_CAPABLE /* No errors are defined for getlocalename_l. So we can't use buffer allocation which might lead to an ENOMEM error. We have to use a "static" buffer here instead. */ - char _getlocalename_l_buf[32 /* ENCODING_LEN + 1 */]; + char _getlocalename_l_buf[7 /* _LC_LAST */ + * 32 /* ENCODING_LEN + 1 */]; +#endif } _reent; #ifdef _REENT_BACKWARD_BINARY_COMPAT struct @@ -764,7 +769,9 @@ struct _reent #define _REENT_L64A_BUF(ptr) ((ptr)->_new._reent._l64a_buf) #define _REENT_SIGNAL_BUF(ptr) ((ptr)->_new._reent._signal_buf) #define _REENT_GETDATE_ERR_P(ptr) (&((ptr)->_new._reent._getdate_err)) +#ifdef _MB_CAPABLE #define _REENT_GETLOCALENAME_L_BUF(ptr)((ptr)->_new._reent._getlocalename_l_buf) +#endif #endif /* !_REENT_SMALL */ diff --git a/newlib/libc/locale/getlocalename_l.c b/newlib/libc/locale/getlocalename_l.c index f32a996..1f18f82 100644 --- a/newlib/libc/locale/getlocalename_l.c +++ b/newlib/libc/locale/getlocalename_l.c @@ -53,11 +53,18 @@ PORTABILITY const char * _getlocalename_l_r (struct _reent *ptr, int category, struct __locale_t *locobj) { - if (category <= LC_ALL || category > LC_MESSAGES) + if (category < LC_ALL || category > LC_MESSAGES) return NULL; #ifndef _MB_CAPABLE return "C"; #else + if (category == LC_ALL) + { + if (locobj == LC_GLOBAL_LOCALE) + return __currentlocale (__get_global_locale (), + _REENT_GETLOCALENAME_L_BUF (ptr)); + return __currentlocale (locobj, locobj->locale_string); + } if (locobj == LC_GLOBAL_LOCALE) { /* getlocalename_l is supposed to return the value in a -- cgit v1.1