Commit 3a2a6ea2 authored by Bruno Haible's avatar Bruno Haible
Browse files

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).
parent 4110c01c
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.
......@@ -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;
}
......
# 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.
......
......@@ -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:
<locale.h>
Link:
$(LIB_DUPLOCALE)
License:
LGPL
......
......@@ -15,3 +15,4 @@ gt_FUNC_USELOCALE
Makefile.am:
TESTS += test-duplocale
check_PROGRAMS += test-duplocale
test_duplocale_LDADD = $(LDADD) @LIB_DUPLOCALE@
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment