summaryrefslogtreecommitdiff
path: root/lib/duplocale.c
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2019-12-15 23:07:28 +0100
committerBruno Haible <bruno@clisp.org>2019-12-15 23:44:03 +0100
commit3a2a6ea2d90664ffef51e6f4be405ea63221dad2 (patch)
tree5ab9e0715907b131abb0061ce910e53800d546ea /lib/duplocale.c
parent4110c01cb60ea810e5f4abb38224eac0b1560462 (diff)
downloadgnulib-3a2a6ea2d90664ffef51e6f4be405ea63221dad2.tar.gz
duplocale: Fix multithread-safety bug on AIX.
* lib/duplocale.c: Don't include <stdlib.h>. (rpl_duplocale): Invoke setlocale_null instead of setlocale. * m4/duplocale.m4 (gl_FUNC_DUPLOCALE): Require gl_FUNC_SETLOCALE_NULL. Set LIB_DUPLOCALE. * modules/duplocale (Depends-on): Add setlocale-null. (Link): New section. * modules/duplocale-tests (Makefile.am): Link test-duplocale with $(LIB_DUPLOCALE).
Diffstat (limited to 'lib/duplocale.c')
-rw-r--r--lib/duplocale.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/lib/duplocale.c b/lib/duplocale.c
index 3b958bab51..d22a447a91 100644
--- a/lib/duplocale.c
+++ b/lib/duplocale.c
@@ -22,7 +22,6 @@
#include <locale.h>
#include <errno.h>
-#include <stdlib.h>
#include <string.h>
#define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
@@ -68,27 +67,33 @@ rpl_duplocale (locale_t locale)
, { LC_IDENTIFICATION, LC_IDENTIFICATION_MASK }
#endif
};
- char *base_name;
+ char base_name[SETLOCALE_NULL_MAX];
+ int err;
locale_t base_copy;
unsigned int i;
- base_name = strdup (setlocale (LC_CTYPE, NULL));
- if (base_name == NULL)
- return NULL;
- base_copy = newlocale (LC_ALL_MASK, base_name, NULL);
- if (base_copy == NULL)
+ err = setlocale_null (LC_CTYPE, base_name, sizeof (base_name));
+ if (err)
{
- int saved_errno = errno;
- free (base_name);
- errno = saved_errno;
+ errno = err;
return NULL;
}
+ base_copy = newlocale (LC_ALL_MASK, base_name, NULL);
+ if (base_copy == NULL)
+ return NULL;
for (i = 0; i < SIZEOF (categories); i++)
{
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 (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);
@@ -96,7 +101,6 @@ rpl_duplocale (locale_t locale)
{
int saved_errno = errno;
freelocale (base_copy);
- free (base_name);
errno = saved_errno;
return NULL;
}
@@ -106,7 +110,6 @@ rpl_duplocale (locale_t locale)
}
}
- free (base_name);
return base_copy;
}