summaryrefslogtreecommitdiff
path: root/lib/duplocale.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/duplocale.c')
-rw-r--r--lib/duplocale.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/lib/duplocale.c b/lib/duplocale.c
index eb7b8d365..430634dbe 100644
--- a/lib/duplocale.c
+++ b/lib/duplocale.c
@@ -1,5 +1,5 @@
/* Duplicate a locale object.
- Copyright (C) 2009-2017 Free Software Foundation, Inc.
+ Copyright (C) 2009-2021 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -12,7 +12,7 @@
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
@@ -32,9 +32,11 @@ locale_t
rpl_duplocale (locale_t locale)
{
/* Work around crash in the duplocale function in glibc < 2.12.
- See <http://sourceware.org/bugzilla/show_bug.cgi?id=10969>.
+ See <https://sourceware.org/bugzilla/show_bug.cgi?id=10969>.
Also, on AIX 7.1, duplocale(LC_GLOBAL_LOCALE) returns (locale_t)0 with
- errno set to EINVAL. */
+ errno set to EINVAL.
+ Also, on NetBSD 7.0, duplocale(LC_GLOBAL_LOCALE) returns a locale that
+ corresponds to the C locale. */
if (locale == LC_GLOBAL_LOCALE)
{
/* Create a copy of the locale by fetching the name of each locale
@@ -65,11 +67,17 @@ rpl_duplocale (locale_t locale)
, { LC_IDENTIFICATION, LC_IDENTIFICATION_MASK }
#endif
};
- const char *base_name;
+ char base_name[SETLOCALE_NULL_MAX];
+ int err;
locale_t base_copy;
unsigned int i;
- base_name = setlocale (LC_CTYPE, NULL);
+ err = setlocale_null_r (LC_CTYPE, base_name, sizeof (base_name));
+ if (err)
+ {
+ errno = err;
+ return NULL;
+ }
base_copy = newlocale (LC_ALL_MASK, base_name, NULL);
if (base_copy == NULL)
return NULL;
@@ -78,7 +86,14 @@ rpl_duplocale (locale_t locale)
{
int category = categories[i].cat;
int category_mask = categories[i].mask;
- const char *name = setlocale (category, NULL);
+ char name[SETLOCALE_NULL_MAX];
+
+ err = setlocale_null_r (category, name, sizeof (name));
+ if (err)
+ {
+ errno = err;
+ return NULL;
+ }
if (strcmp (name, base_name) != 0)
{
locale_t copy = newlocale (category_mask, name, base_copy);