From 3a2a6ea2d90664ffef51e6f4be405ea63221dad2 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 15 Dec 2019 23:07:28 +0100 Subject: [PATCH] duplocale: Fix multithread-safety bug on AIX. * lib/duplocale.c: Don't include . (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). --- ChangeLog | 12 ++++++++++++ lib/duplocale.c | 29 ++++++++++++++++------------- m4/duplocale.m4 | 9 ++++++++- modules/duplocale | 4 ++++ modules/duplocale-tests | 1 + 5 files changed, 41 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index af1d5bf903..4f46f01a4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2019-12-15 Bruno Haible + + duplocale: Fix multithread-safety bug on AIX. + * lib/duplocale.c: Don't include . + (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 setlocale-null: Add tests. 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 #include -#include #include #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; } diff --git a/m4/duplocale.m4 b/m4/duplocale.m4 index fb5e602a09..3900b53b5e 100644 --- a/m4/duplocale.m4 +++ b/m4/duplocale.m4 @@ -1,4 +1,4 @@ -# 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, @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_DUPLOCALE], [ 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. @@ -109,6 +110,12 @@ int main () 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. diff --git a/modules/duplocale b/modules/duplocale index 08eca3c261..aaa12cd09d 100644 --- a/modules/duplocale +++ b/modules/duplocale @@ -7,6 +7,7 @@ m4/duplocale.m4 Depends-on: locale +setlocale-null [test $REPLACE_DUPLOCALE = 1] configure.ac: gl_FUNC_DUPLOCALE @@ -21,6 +22,9 @@ Makefile.am: Include: +Link: +$(LIB_DUPLOCALE) + License: LGPL diff --git a/modules/duplocale-tests b/modules/duplocale-tests index 29b2a1a02d..6545c4e33a 100644 --- a/modules/duplocale-tests +++ b/modules/duplocale-tests @@ -15,3 +15,4 @@ gt_FUNC_USELOCALE Makefile.am: TESTS += test-duplocale check_PROGRAMS += test-duplocale +test_duplocale_LDADD = $(LDADD) @LIB_DUPLOCALE@ -- 2.39.5