diff options
Diffstat (limited to 'locale')
-rw-r--r-- | locale/duplocale.c | 4 | ||||
-rw-r--r-- | locale/freelocale.c | 4 | ||||
-rw-r--r-- | locale/newlocale.c | 11 |
3 files changed, 19 insertions, 0 deletions
diff --git a/locale/duplocale.c b/locale/duplocale.c index 2fa29d14d6..77dfc01046 100644 --- a/locale/duplocale.c +++ b/locale/duplocale.c @@ -33,6 +33,10 @@ __libc_lock_define (extern , __libc_setlocale_lock attribute_hidden) __locale_t __duplocale (__locale_t dataset) { + /* This static object is returned for newlocale (LC_ALL_MASK, "C"). */ + if (dataset == &_nl_C_locobj) + return dataset; + __locale_t result; int cnt; size_t names_len = 0; diff --git a/locale/freelocale.c b/locale/freelocale.c index ba0ae85d84..ec169bcb66 100644 --- a/locale/freelocale.c +++ b/locale/freelocale.c @@ -34,6 +34,10 @@ __freelocale (__locale_t dataset) { int cnt; + /* This static object is returned for newlocale (LC_ALL_MASK, "C"). */ + if (dataset == &_nl_C_locobj) + return; + /* We modify global data (the usage counts). */ __libc_lock_lock (__libc_setlocale_lock); diff --git a/locale/newlocale.c b/locale/newlocale.c index 3b8676ceeb..1131f62c0b 100644 --- a/locale/newlocale.c +++ b/locale/newlocale.c @@ -60,6 +60,17 @@ __newlocale (int category_mask, const char *locale, __locale_t base) if (locale == NULL) ERROR_RETURN; + if (base == &_nl_C_locobj) + /* We're to modify BASE, returned for a previous call with "C". + We can't really modify the read-only structure, so instead + start over by copying it. */ + base = NULL; + + if ((base == NULL || category_mask == (1 << __LC_LAST) - 1 - (1 << LC_ALL)) + && (category_mask == 0 || !strcmp (locale, "C"))) + /* Asking for the "C" locale needn't allocate a new object. */ + return &_nl_C_locobj; + /* Allocate memory for the result. */ if (base != NULL) result = *base; |