* 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).
+2019-12-15 Bruno Haible <bruno@clisp.org>
+
+ 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).
+
2019-12-15 Bruno Haible <bruno@clisp.org>
setlocale-null: Add tests.
#include <locale.h>
#include <errno.h>
-#include <stdlib.h>
#include <string.h>
#define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
, { 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);
{
int saved_errno = errno;
freelocale (base_copy);
- free (base_name);
errno = saved_errno;
return NULL;
}
}
}
- free (base_name);
return base_copy;
}
-# duplocale.m4 serial 11
+# duplocale.m4 serial 12
dnl Copyright (C) 2009-2019 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
[
AC_REQUIRE([gl_LOCALE_H_DEFAULTS])
AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_REQUIRE([gl_FUNC_SETLOCALE_NULL])
AC_CHECK_FUNCS_ONCE([duplocale])
if test $ac_cv_func_duplocale = yes; then
dnl Check against glibc bug where duplocale crashes.
else
HAVE_DUPLOCALE=0
fi
+ if test $REPLACE_DUPLOCALE = 1; then
+ LIB_DUPLOCALE="$LIB_SETLOCALE_NULL"
+ else
+ LIB_DUPLOCALE=
+ fi
+ AC_SUBST([LIB_DUPLOCALE])
])
# Prerequisites of lib/duplocale.c.
Depends-on:
locale
+setlocale-null [test $REPLACE_DUPLOCALE = 1]
configure.ac:
gl_FUNC_DUPLOCALE
Include:
<locale.h>
+Link:
+$(LIB_DUPLOCALE)
+
License:
LGPL
Makefile.am:
TESTS += test-duplocale
check_PROGRAMS += test-duplocale
+test_duplocale_LDADD = $(LDADD) @LIB_DUPLOCALE@