aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2025-03-24 21:28:02 +0100
committerCorinna Vinschen <corinna@vinschen.de>2025-03-24 21:28:47 +0100
commita0fe984953ddaa808a00612b5c6959d1c3987a2d (patch)
tree55cc9d12e959079b84eb1a3f619f09f7f6a94a8d
parente5a9f552ecf908f1639b08729edc191c66f4e7d0 (diff)
downloadnewlib-a0fe984953ddaa808a00612b5c6959d1c3987a2d.zip
newlib-a0fe984953ddaa808a00612b5c6959d1c3987a2d.tar.gz
newlib-a0fe984953ddaa808a00612b5c6959d1c3987a2d.tar.bz2
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 <corinna@vinschen.de>
-rw-r--r--newlib/libc/include/sys/reent.h11
-rw-r--r--newlib/libc/locale/getlocalename_l.c9
2 files changed, 17 insertions, 3 deletions
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