[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
setlocale: make calls with NULL argument multithread-safe
From: |
Bruno Haible |
Subject: |
setlocale: make calls with NULL argument multithread-safe |
Date: |
Wed, 18 Dec 2019 14:47:32 +0100 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-166-generic; KDE/5.18.0; x86_64; ; ) |
This patch makes use of the 'setlocale-null' module, to make the
setlocale(..., NULL) calls multithread-safe.
Use of setlocale(), with the gnulib override, now requires linking
with $(LIB_SETLOCALE) - to avoid link errors on AIX.
Although we now have two modules 'setlocale-null' and 'setlocale'
with the same multithread-safety fix, there are several «raisons d'être»
for 'setlocale-null':
- It is the simplest API - does not require static or per-thread
buffers.
- When used in a library, it does not add several kB of BSS space
to the library.
- It has the minimal module dependencies - no need for 'localename'.
- It does not contain the other improvements on setlocale (mapping
of locale names, etc.) that require big tables.
- If the values of SETLOCALE_NULL_MAX and SETLOCALE_NULL_ALL_MAX
turn out to be too small in a particular use-case, users of
module 'setlocale-null' can request a larger buffer, while users
module 'setlocale' cannot do this (without modifying the source code).
2019-12-18 Bruno Haible <address@hidden>
setlocale: Make calls with NULL argument multithread-safe.
* lib/setlocale.c: Include <errno.h>.
(setlocale_mtsafe): New function.
(setlocale_unixlike): Invoke setlocale_mtsafe instead of setlocale.
(setlocale_improved): Renamed from rpl_setlocale.
* m4/setlocale.m4 (gl_FUNC_SETLOCALE): Require gl_FUNC_SETLOCALE_NULL.
Set and define NEED_SETLOCALE_IMPROVED and NEED_SETLOCALE_MTSAFE. Set
LIB_SETLOCALE.
* modules/setlocale (Depends-on): Add setlocale-null. Update conditions.
(Link): New section.
* tests/locale.c: Undefine setlocale.
* tests/test-setlocale_null-one.c: Likewise.
* tests/test-setlocale_null-all.c: Likewise.
* modules/setlocale-tests (Makefile.am): Link the test programs with
$(LIB_SETLOCALE).
* modules/astrxfrm-tests (Makefile.am): Likewise.
* modules/btowc-tests (Makefile.am): Likewise.
* modules/c-ctype-tests (Makefile.am): Likewise.
* modules/c-snprintf-tests (Makefile.am): Likewise.
* modules/c-strcase-tests (Makefile.am): Likewise.
* modules/c-vasprintf-tests (Makefile.am): Likewise.
* modules/c-vsnprintf-tests (Makefile.am): Likewise.
* modules/c-xvasprintf-tests (Makefile.am): Likewise.
* modules/dfa-tests (Makefile.am): Likewise.
* modules/duplocale-tests (Makefile.am): Likewise.
* modules/hard-locale-tests (Makefile.am): Likewise.
* modules/localcharset-tests (Makefile.am): Likewise.
* modules/localename-tests (Makefile.am): Likewise.
* modules/mbmemcasecmp-tests (Makefile.am): Likewise.
* modules/mbmemcasecoll-tests (Makefile.am): Likewise.
* modules/mbrtowc-tests (Makefile.am): Likewise.
* modules/mbscasecmp-tests (Makefile.am): Likewise.
* modules/mbscasestr-tests (Makefile.am): Likewise.
* modules/mbschr-tests (Makefile.am): Likewise.
* modules/mbscspn-tests (Makefile.am): Likewise.
* modules/mbsinit-tests (Makefile.am): Likewise.
* modules/mbsncasecmp-tests (Makefile.am): Likewise.
* modules/mbsnrtowcs-tests (Makefile.am): Likewise.
* modules/mbspbrk-tests (Makefile.am): Likewise.
* modules/mbspcasecmp-tests (Makefile.am): Likewise.
* modules/mbsrchr-tests (Makefile.am): Likewise.
* modules/mbsrtowcs-tests (Makefile.am): Likewise.
* modules/mbsspn-tests (Makefile.am): Likewise.
* modules/mbsstr-tests (Makefile.am): Likewise.
* modules/nl_langinfo-tests (Makefile.am): Likewise.
* modules/quotearg-tests (Makefile.am): Likewise.
* modules/regex-tests (Makefile.am): Likewise.
* modules/strfmon_l-tests (Makefile.am): Likewise.
* modules/strtod-tests (Makefile.am): Likewise.
* modules/strtold-tests (Makefile.am): Likewise.
* modules/unicase/locale-language-tests (Makefile.am): Likewise.
* modules/unicase/ulc-casecmp-tests (Makefile.am): Likewise.
* modules/unicase/ulc-casecoll-tests (Makefile.am): Likewise.
* modules/unigbrk/ulc-grapheme-breaks-tests (Makefile.am): Likewise.
* modules/unistdio/u8-vasnprintf-tests (Makefile.am): Likewise.
* modules/unistdio/u16-vasnprintf-tests (Makefile.am): Likewise.
* modules/unistdio/u32-vasnprintf-tests (Makefile.am): Likewise.
* modules/unistdio/ulc-vasnprintf-tests (Makefile.am): Likewise.
* modules/uniwbrk/ulc-wordbreaks-tests (Makefile.am): Likewise.
* modules/vasnprintf-posix-tests (Makefile.am): Likewise.
* modules/wcrtomb-tests (Makefile.am): Likewise.
* modules/wcsnrtombs-tests (Makefile.am): Likewise.
* modules/wcsrtombs-tests (Makefile.am): Likewise.
* modules/wcwidth-tests (Makefile.am): Likewise.
* doc/posix-functions/setlocale.texi: Mention that the multithread-
safety fix is also available in module 'setlocale'.
diff --git a/doc/posix-functions/setlocale.texi
b/doc/posix-functions/setlocale.texi
index cd172c0..d8282b6 100644
--- a/doc/posix-functions/setlocale.texi
+++ b/doc/posix-functions/setlocale.texi
@@ -26,14 +26,15 @@ always fails. The replacement, however, supports only the
locale names
@code{"C"} and @code{"POSIX"}.
@end itemize
-Portability problems fixed by Gnulib module @code{setlocale-null}:
+Portability problems fixed by Gnulib module @code{setlocale} or
@code{setlocale-null}:
@itemize
@item
Invocations of @code{setlocale (..., NULL)} are not multithread-safe on some
platforms:
musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin.
-To make these invocations multithread-safe, you need to change the code to
-invoke @code{setlocale_null} instead.
+To make these invocations multithread-safe, you need the Gnulib module
+@code{setlocale}, or you need to change the code to invoke
@code{setlocale_null}
+instead.
@end itemize
Portability problems not fixed by Gnulib:
diff --git a/lib/setlocale.c b/lib/setlocale.c
index fbabe99..da28a1a 100644
--- a/lib/setlocale.c
+++ b/lib/setlocale.c
@@ -29,6 +29,7 @@
/* Specification. */
#include <locale.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -51,6 +52,141 @@ extern void gl_locale_name_canonicalize (char *name);
# undef setlocale
+/* Which of the replacements to activate? */
+# if NEED_SETLOCALE_IMPROVED
+# define setlocale_improved rpl_setlocale
+# elif NEED_SETLOCALE_MTSAFE
+# define setlocale_mtsafe rpl_setlocale
+# else
+# error "This file should only be compiled if NEED_SETLOCALE_IMPROVED ||
NEED_SETLOCALE_MTSAFE."
+# endif
+
+/* Like setlocale, but guaranteed to be multithread-safe if LOCALE == NULL. */
+# if !SETLOCALE_NULL_ALL_MTSAFE || !SETLOCALE_NULL_ONE_MTSAFE /* i.e. if
NEED_SETLOCALE_MTSAFE */
+
+# if NEED_SETLOCALE_IMPROVED
+static
+# endif
+char *
+setlocale_mtsafe (int category, const char *locale)
+{
+ if (locale == NULL)
+ {
+ /* This call must be multithread-safe. To achieve this without using
+ thread-local storage:
+ 1. We use a specific static buffer for each possible CATEGORY
+ argument. So that different threads can call setlocale_mtsafe
+ with different CATEGORY arguments, without interfering.
+ 2. We use a simple strcpy or memcpy to fill this static buffer.
+ Filling it through, for example, strcpy + strcat would not be
+ guaranteed to leave the buffer's contents intact if another
thread
+ is currently accessing it. If necessary, the contents is first
+ assembled in a stack-allocated buffer. */
+ if (category == LC_ALL)
+ {
+# if SETLOCALE_NULL_ALL_MTSAFE
+ return setlocale (LC_ALL, NULL);
+# else
+ char buf[SETLOCALE_NULL_ALL_MAX];
+ static char resultbuf[SETLOCALE_NULL_ALL_MAX];
+
+ if (setlocale_null (LC_ALL, buf, sizeof (buf)))
+ return (char *) "C";
+ strcpy (resultbuf, buf);
+ return resultbuf;
+# endif
+ }
+ else
+ {
+# if SETLOCALE_NULL_ONE_MTSAFE
+ return setlocale (category, NULL);
+# else
+ enum
+ {
+ LC_CTYPE_INDEX,
+ LC_NUMERIC_INDEX,
+ LC_TIME_INDEX,
+ LC_COLLATE_INDEX,
+ LC_MONETARY_INDEX,
+ LC_MESSAGES_INDEX,
+# ifdef LC_PAPER
+ LC_PAPER_INDEX,
+# endif
+# ifdef LC_NAME
+ LC_NAME_INDEX,
+# endif
+# ifdef LC_ADDRESS
+ LC_ADDRESS_INDEX,
+# endif
+# ifdef LC_TELEPHONE
+ LC_TELEPHONE_INDEX,
+# endif
+# ifdef LC_MEASUREMENT
+ LC_MEASUREMENT_INDEX,
+# endif
+# ifdef LC_IDENTIFICATION
+ LC_IDENTIFICATION_INDEX,
+# endif
+ LC_INDICES_COUNT
+ }
+ i;
+ char buf[SETLOCALE_NULL_MAX];
+ static char resultbuf[LC_INDICES_COUNT][SETLOCALE_NULL_MAX];
+ int err;
+
+ err = setlocale_null (category, buf, sizeof (buf));
+ if (err == EINVAL)
+ return NULL;
+ if (err)
+ return (char *) "C";
+
+ switch (category)
+ {
+ case LC_CTYPE: i = LC_CTYPE_INDEX; break;
+ case LC_NUMERIC: i = LC_NUMERIC_INDEX; break;
+ case LC_TIME: i = LC_TIME_INDEX; break;
+ case LC_COLLATE: i = LC_COLLATE_INDEX; break;
+ case LC_MONETARY: i = LC_MONETARY_INDEX; break;
+ case LC_MESSAGES: i = LC_MESSAGES_INDEX; break;
+# ifdef LC_PAPER
+ case LC_PAPER: i = LC_PAPER_INDEX; break;
+# endif
+# ifdef LC_NAME
+ case LC_NAME: i = LC_NAME_INDEX; break;
+# endif
+# ifdef LC_ADDRESS
+ case LC_ADDRESS: i = LC_ADDRESS_INDEX; break;
+# endif
+# ifdef LC_TELEPHONE
+ case LC_TELEPHONE: i = LC_TELEPHONE_INDEX; break;
+# endif
+# ifdef LC_MEASUREMENT
+ case LC_MEASUREMENT: i = LC_MEASUREMENT_INDEX; break;
+# endif
+# ifdef LC_IDENTIFICATION
+ case LC_IDENTIFICATION: i = LC_IDENTIFICATION_INDEX; break;
+# endif
+ default:
+ /* If you get here, a #ifdef LC_xxx is missing. */
+ abort ();
+ }
+
+ strcpy (resultbuf[i], buf);
+ return resultbuf[i];
+# endif
+ }
+ }
+ else
+ return setlocale (category, locale);
+}
+# else /* !NEED_SETLOCALE_MTSAFE */
+
+# define setlocale_mtsafe setlocale
+
+# endif /* NEED_SETLOCALE_MTSAFE */
+
+# if NEED_SETLOCALE_IMPROVED
+
/* Return string representation of locale category CATEGORY. */
static const char *
category_to_name (int category)
@@ -85,7 +221,7 @@ category_to_name (int category)
return retval;
}
-# if defined _WIN32 && ! defined __CYGWIN__
+# if defined _WIN32 && ! defined __CYGWIN__
/* The native Windows setlocale() function expects locale names of the form
"German" or "German_Germany" or "DEU", but not "de" or "de_DE". We need
@@ -652,7 +788,7 @@ setlocale_unixlike (int category, const char *locale)
locale = "C";
/* First, try setlocale with the original argument unchanged. */
- result = setlocale (category, locale);
+ result = setlocale_mtsafe (category, locale);
if (result != NULL)
return result;
@@ -794,13 +930,13 @@ setlocale_unixlike (int category, const char *locale)
return NULL;
}
-# elif defined __ANDROID__
+# elif defined __ANDROID__
/* Like setlocale, but accept also the locale names "C" and "POSIX". */
static char *
setlocale_unixlike (int category, const char *locale)
{
- char *result = setlocale (category, locale);
+ char *result = setlocale_mtsafe (category, locale);
if (result == NULL)
switch (category)
{
@@ -825,13 +961,13 @@ setlocale_unixlike (int category, const char *locale)
}
return result;
}
-# define setlocale setlocale_unixlike
+# define setlocale setlocale_unixlike
-# else
-# define setlocale_unixlike setlocale
-# endif
+# else
+# define setlocale_unixlike setlocale_mtsafe
+# endif
-# if LC_MESSAGES == 1729
+# if LC_MESSAGES == 1729
/* The system does not store an LC_MESSAGES locale category. Do it here. */
static char lc_messages_name[64] = "C";
@@ -853,11 +989,11 @@ setlocale_single (int category, const char *locale)
return setlocale_unixlike (category, locale);
}
-# else
-# define setlocale_single setlocale_unixlike
-# endif
+# else
+# define setlocale_single setlocale_unixlike
+# endif
-# if defined __APPLE__ && defined __MACH__
+# if defined __APPLE__ && defined __MACH__
/* Mapping from language to main territory where that language is spoken. */
static char const locales_with_principal_territory[][6 + 1] =
@@ -1115,7 +1251,7 @@ langcmp (const char *locale1, const char *locale2)
static const char *
get_main_locale_with_same_language (const char *locale)
{
-# define table locales_with_principal_territory
+# define table locales_with_principal_territory
/* The table is sorted. Perform a binary search. */
size_t hi = sizeof (table) / sizeof (table[0]);
size_t lo = 0;
@@ -1142,7 +1278,7 @@ get_main_locale_with_same_language (const char *locale)
return table[mid];
}
}
-# undef table
+# undef table
return NULL;
}
@@ -1344,7 +1480,7 @@ get_main_locale_with_same_territory (const char *locale)
{
if (strrchr (locale, '_') != NULL)
{
-# define table locales_with_principal_language
+# define table locales_with_principal_language
/* The table is sorted. Perform a binary search. */
size_t hi = sizeof (table) / sizeof (table[0]);
size_t lo = 0;
@@ -1371,15 +1507,15 @@ get_main_locale_with_same_territory (const char *locale)
return table[mid];
}
}
-# undef table
+# undef table
}
return NULL;
}
-# endif
+# endif
char *
-rpl_setlocale (int category, const char *locale)
+setlocale_improved (int category, const char *locale)
{
if (locale != NULL && locale[0] == '\0')
{
@@ -1431,14 +1567,14 @@ rpl_setlocale (int category, const char *locale)
goto fail;
i = 0;
}
-# if defined _WIN32 && ! defined __CYGWIN__
+# if defined _WIN32 && ! defined __CYGWIN__
/* On native Windows, setlocale(LC_ALL,...) may succeed but set the
LC_CTYPE category to an invalid value ("C") when it does not
support the specified encoding. Report a failure instead. */
if (strchr (base_name, '.') != NULL
&& strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
goto fail;
-# endif
+# endif
for (; i < sizeof (categories) / sizeof (categories[0]); i++)
{
@@ -1452,12 +1588,12 @@ rpl_setlocale (int category, const char *locale)
/* If name is the same as base_name, it has already been set
through the setlocale call before the loop. */
if (strcmp (name, base_name) != 0
-# if LC_MESSAGES == 1729
+# if LC_MESSAGES == 1729
|| cat == LC_MESSAGES
-# endif
+# endif
)
if (setlocale_single (cat, name) == NULL)
-# if defined __APPLE__ && defined __MACH__
+# if defined __APPLE__ && defined __MACH__
{
/* On Mac OS X 10.13, some locales can be set through
System Preferences > Language & Region, that are not
@@ -1473,11 +1609,11 @@ rpl_setlocale (int category, const char *locale)
warn = (setlocale_single (cat, "UTF-8") == NULL);
else if (cat == LC_MESSAGES)
{
-# if HAVE_CFLOCALECOPYPREFERREDLANGUAGES || HAVE_CFPREFERENCESCOPYAPPVALUE /*
MacOS X 10.4 or newer */
+# if HAVE_CFLOCALECOPYPREFERREDLANGUAGES || HAVE_CFPREFERENCESCOPYAPPVALUE
/* MacOS X 10.4 or newer */
/* Take the primary language preference. */
-# if HAVE_CFLOCALECOPYPREFERREDLANGUAGES /* MacOS X 10.5 or newer */
+# if HAVE_CFLOCALECOPYPREFERREDLANGUAGES /* MacOS X 10.5 or newer */
CFArrayRef prefArray = CFLocaleCopyPreferredLanguages
();
-# elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.4 or newer */
+# elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.4 or newer */
CFTypeRef preferences =
CFPreferencesCopyAppValue (CFSTR ("AppleLanguages"),
kCFPreferencesCurrentApplication);
@@ -1485,7 +1621,7 @@ rpl_setlocale (int category, const char *locale)
&& CFGetTypeID (preferences) == CFArrayGetTypeID
())
{
CFArrayRef prefArray = (CFArrayRef)preferences;
-# endif
+# endif
int n = CFArrayGetCount (prefArray);
if (n > 0)
{
@@ -1519,19 +1655,19 @@ rpl_setlocale (int category, const char *locale)
}
}
}
-# if HAVE_CFLOCALECOPYPREFERREDLANGUAGES /* MacOS X 10.5 or newer */
+# if HAVE_CFLOCALECOPYPREFERREDLANGUAGES /* MacOS X 10.5 or newer */
CFRelease (prefArray);
-# elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.4 or newer */
+# elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.4 or newer */
}
-# endif
-# else
+# endif
+# else
const char *last_try =
get_main_locale_with_same_language (name);
if (last_try == NULL
|| setlocale_single (cat, last_try) == NULL)
warn = 1;
-# endif
+# endif
}
else
{
@@ -1570,9 +1706,9 @@ rpl_setlocale (int category, const char *locale)
category_to_name (cat), name);
}
}
-# else
+# else
goto fail;
-# endif
+# endif
}
/* All steps were successful. */
@@ -1597,7 +1733,7 @@ rpl_setlocale (int category, const char *locale)
}
else
{
-# if defined _WIN32 && ! defined __CYGWIN__
+# if defined _WIN32 && ! defined __CYGWIN__
if (category == LC_ALL && locale != NULL && strchr (locale, '.') != NULL)
{
char *saved_locale;
@@ -1632,9 +1768,11 @@ rpl_setlocale (int category, const char *locale)
return setlocale (LC_ALL, NULL);
}
else
-# endif
+# endif
return setlocale_single (category, locale);
}
}
+# endif /* NEED_SETLOCALE_IMPROVED */
+
#endif
diff --git a/m4/setlocale.m4 b/m4/setlocale.m4
index dba68c4..14f22b2 100644
--- a/m4/setlocale.m4
+++ b/m4/setlocale.m4
@@ -1,4 +1,4 @@
-# setlocale.m4 serial 6
+# setlocale.m4 serial 7
dnl Copyright (C) 2011-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,
@@ -7,16 +7,20 @@ dnl with or without modifications, as long as this notice is
preserved.
AC_DEFUN([gl_FUNC_SETLOCALE],
[
AC_REQUIRE([gl_LOCALE_H_DEFAULTS])
+ AC_REQUIRE([gl_FUNC_SETLOCALE_NULL])
AC_REQUIRE([AC_CANONICAL_HOST])
+
+ dnl Test whether we need to improve on the general working of setlocale.
+ NEED_SETLOCALE_IMPROVED=0
case "$host_os" in
dnl On native Windows systems, setlocale(category,NULL) does not look at
dnl the environment variables LC_ALL, category, and LANG.
- mingw*) REPLACE_SETLOCALE=1 ;;
+ mingw*) NEED_SETLOCALE_IMPROVED=1 ;;
dnl On Cygwin 1.5.x, setlocale always succeeds but setlocale(LC_CTYPE,NULL)
dnl is then still "C".
cygwin*)
case `uname -r` in
- 1.5.*) REPLACE_SETLOCALE=1 ;;
+ 1.5.*) NEED_SETLOCALE_IMPROVED=1 ;;
esac
;;
dnl On Android 4.3, setlocale(category,"C") always fails.
@@ -42,10 +46,33 @@ int main ()
])
case "$gl_cv_func_setlocale_works" in
*yes) ;;
- *) REPLACE_SETLOCALE=1 ;;
+ *) NEED_SETLOCALE_IMPROVED=1 ;;
esac
;;
esac
+ AC_DEFINE_UNQUOTED([NEED_SETLOCALE_IMPROVED], [$NEED_SETLOCALE_IMPROVED],
+ [Define to 1 to enable general improvements of setlocale.])
+
+ dnl Test whether we need a multithread-safe setlocale(category,NULL).
+ NEED_SETLOCALE_MTSAFE=0
+ if test $SETLOCALE_NULL_ALL_MTSAFE = 0 || test $SETLOCALE_NULL_ONE_MTSAFE =
0; then
+ NEED_SETLOCALE_MTSAFE=1
+ fi
+ AC_DEFINE_UNQUOTED([NEED_SETLOCALE_MTSAFE], [$NEED_SETLOCALE_MTSAFE],
+ [Define to 1 to enable a multithread-safety fix of setlocale.])
+
+ if test $NEED_SETLOCALE_IMPROVED = 1 || test $NEED_SETLOCALE_MTSAFE = 1; then
+ REPLACE_SETLOCALE=1
+ fi
+
+ if test $NEED_SETLOCALE_MTSAFE = 1; then
+ LIB_SETLOCALE="$LIB_SETLOCALE_NULL"
+ else
+ LIB_SETLOCALE=
+ fi
+ dnl LIB_SETLOCALE is expected to be '-pthread' or '-lpthread' on AIX with gcc
+ dnl or xlc, and empty otherwise.
+ AC_SUBST([LIB_SETLOCALE])
])
# Prerequisites of lib/setlocale.c.
diff --git a/modules/astrxfrm-tests b/modules/astrxfrm-tests
index af8c100..b113e34 100644
--- a/modules/astrxfrm-tests
+++ b/modules/astrxfrm-tests
@@ -9,3 +9,4 @@ configure.ac:
Makefile.am:
TESTS += test-astrxfrm
check_PROGRAMS += test-astrxfrm
+test_astrxfrm_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/btowc-tests b/modules/btowc-tests
index 66196b1..e36cc61 100644
--- a/modules/btowc-tests
+++ b/modules/btowc-tests
@@ -18,4 +18,4 @@ Makefile.am:
TESTS += test-btowc1.sh test-btowc2.sh
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-btowc
-
+test_btowc_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/c-ctype-tests b/modules/c-ctype-tests
index e66a4cc..02706b0 100644
--- a/modules/c-ctype-tests
+++ b/modules/c-ctype-tests
@@ -11,3 +11,4 @@ configure.ac:
Makefile.am:
TESTS += test-c-ctype
check_PROGRAMS += test-c-ctype
+test_c_ctype_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/c-snprintf-tests b/modules/c-snprintf-tests
index 86d6a14..231a4fd 100644
--- a/modules/c-snprintf-tests
+++ b/modules/c-snprintf-tests
@@ -13,5 +13,6 @@ gt_LOCALE_FR
Makefile.am:
TESTS += test-c-snprintf.sh
-check_PROGRAMS += test-c-snprintf
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@'
+check_PROGRAMS += test-c-snprintf
+test_c_snprintf_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/c-strcase-tests b/modules/c-strcase-tests
index 5802f41..7cdb29c 100644
--- a/modules/c-strcase-tests
+++ b/modules/c-strcase-tests
@@ -19,3 +19,5 @@ Makefile.am:
TESTS += test-c-strcase.sh
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_TR_UTF8='@LOCALE_TR_UTF8@'
check_PROGRAMS += test-c-strcasecmp test-c-strncasecmp
+test_c_strcasecmp_LDADD = $(LDADD) $(LIB_SETLOCALE)
+test_c_strncasecmp_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/c-vasprintf-tests b/modules/c-vasprintf-tests
index 9409563..b82fc8b 100644
--- a/modules/c-vasprintf-tests
+++ b/modules/c-vasprintf-tests
@@ -13,5 +13,6 @@ gt_LOCALE_FR
Makefile.am:
TESTS += test-c-vasprintf.sh
-check_PROGRAMS += test-c-vasprintf
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@'
+check_PROGRAMS += test-c-vasprintf
+test_c_vasprintf_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/c-vsnprintf-tests b/modules/c-vsnprintf-tests
index 6a76092..542d8d9 100644
--- a/modules/c-vsnprintf-tests
+++ b/modules/c-vsnprintf-tests
@@ -13,5 +13,6 @@ gt_LOCALE_FR
Makefile.am:
TESTS += test-c-vsnprintf.sh
-check_PROGRAMS += test-c-vsnprintf
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@'
+check_PROGRAMS += test-c-vsnprintf
+test_c_vsnprintf_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/c-xvasprintf-tests b/modules/c-xvasprintf-tests
index a118de0..75ce919 100644
--- a/modules/c-xvasprintf-tests
+++ b/modules/c-xvasprintf-tests
@@ -14,6 +14,6 @@ gt_LOCALE_FR
Makefile.am:
TESTS += test-c-xvasprintf.sh
-check_PROGRAMS += test-c-xvasprintf
-test_c_xvasprintf_LDADD = $(LDADD) @LIBINTL@
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@'
+check_PROGRAMS += test-c-xvasprintf
+test_c_xvasprintf_LDADD = $(LDADD) $(LIB_SETLOCALE) @LIBINTL@
diff --git a/modules/dfa-tests b/modules/dfa-tests
index ee4354a..0128dca 100644
--- a/modules/dfa-tests
+++ b/modules/dfa-tests
@@ -18,4 +18,4 @@ TESTS += \
dfa-match.sh
check_PROGRAMS += dfa-match-aux
-dfa_match_aux_LDADD = $(LDADD) @LIBINTL@ $(LIBTHREAD)
+dfa_match_aux_LDADD = $(LDADD) $(LIB_SETLOCALE) @LIBINTL@ $(LIBTHREAD)
diff --git a/modules/duplocale-tests b/modules/duplocale-tests
index 6545c4e..e308109 100644
--- a/modules/duplocale-tests
+++ b/modules/duplocale-tests
@@ -15,4 +15,4 @@ gt_FUNC_USELOCALE
Makefile.am:
TESTS += test-duplocale
check_PROGRAMS += test-duplocale
-test_duplocale_LDADD = $(LDADD) @LIB_DUPLOCALE@
+test_duplocale_LDADD = $(LDADD) $(LIB_SETLOCALE) @LIB_DUPLOCALE@
diff --git a/modules/hard-locale-tests b/modules/hard-locale-tests
index a501781..ddd101f 100644
--- a/modules/hard-locale-tests
+++ b/modules/hard-locale-tests
@@ -16,4 +16,4 @@ Makefile.am:
TESTS += test-hard-locale
check_PROGRAMS += test-hard-locale
noinst_PROGRAMS += locale
-test_hard_locale_LDADD = $(LDADD) @LIB_HARD_LOCALE@
+test_hard_locale_LDADD = $(LDADD) $(LIB_SETLOCALE) @LIB_HARD_LOCALE@
diff --git a/modules/localcharset-tests b/modules/localcharset-tests
index 52e4c60..70d5cfd 100644
--- a/modules/localcharset-tests
+++ b/modules/localcharset-tests
@@ -7,3 +7,4 @@ configure.ac:
Makefile.am:
noinst_PROGRAMS += test-localcharset
+test_localcharset_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/localename-tests b/modules/localename-tests
index 4940965..4b9a28a 100644
--- a/modules/localename-tests
+++ b/modules/localename-tests
@@ -15,5 +15,5 @@ AC_CHECK_FUNCS_ONCE([newlocale])
Makefile.am:
TESTS += test-localename
check_PROGRAMS += test-localename
-test_localename_LDADD = $(LDADD) @INTL_MACOSX_LIBS@ $(LIBTHREAD)
+test_localename_LDADD = $(LDADD) $(LIB_SETLOCALE) @INTL_MACOSX_LIBS@
$(LIBTHREAD)
diff --git a/modules/mbmemcasecmp-tests b/modules/mbmemcasecmp-tests
index 29c8cf6..16a1123 100644
--- a/modules/mbmemcasecmp-tests
+++ b/modules/mbmemcasecmp-tests
@@ -25,4 +25,4 @@ TESTS_ENVIRONMENT += \
LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
LOCALE_TR_UTF8='@LOCALE_TR_UTF8@'
check_PROGRAMS += test-mbmemcasecmp
-test_mbmemcasecmp_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbmemcasecmp_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbmemcasecoll-tests b/modules/mbmemcasecoll-tests
index fb308d9..56a3db0 100644
--- a/modules/mbmemcasecoll-tests
+++ b/modules/mbmemcasecoll-tests
@@ -25,4 +25,4 @@ TESTS_ENVIRONMENT += \
LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
LOCALE_TR_UTF8='@LOCALE_TR_UTF8@'
check_PROGRAMS += test-mbmemcasecoll
-test_mbmemcasecoll_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbmemcasecoll_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbrtowc-tests b/modules/mbrtowc-tests
index a2839cb..86008d8 100644
--- a/modules/mbrtowc-tests
+++ b/modules/mbrtowc-tests
@@ -41,4 +41,4 @@ TESTS_ENVIRONMENT += \
LOCALE_JA='@LOCALE_JA@' \
LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-mbrtowc test-mbrtowc-w32
-test_mbrtowc_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbrtowc_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbscasecmp-tests b/modules/mbscasecmp-tests
index 8548050..9f77064 100644
--- a/modules/mbscasecmp-tests
+++ b/modules/mbscasecmp-tests
@@ -15,4 +15,4 @@ Makefile.am:
TESTS += test-mbscasecmp.sh
TESTS_ENVIRONMENT += LOCALE_TR_UTF8='@LOCALE_TR_UTF8@'
check_PROGRAMS += test-mbscasecmp
-test_mbscasecmp_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbscasecmp_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbscasestr-tests b/modules/mbscasestr-tests
index bc2df73..3395c1f 100644
--- a/modules/mbscasestr-tests
+++ b/modules/mbscasestr-tests
@@ -25,6 +25,6 @@ TESTS += test-mbscasestr1 test-mbscasestr2.sh
test-mbscasestr3.sh test-mbscasest
TESTS_ENVIRONMENT += LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
LOCALE_TR_UTF8='@LOCALE_TR_UTF8@' LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-mbscasestr1 test-mbscasestr2 test-mbscasestr3
test-mbscasestr4
test_mbscasestr1_LDADD = $(LDADD) $(LIBTHREAD)
-test_mbscasestr2_LDADD = $(LDADD) $(LIBTHREAD)
-test_mbscasestr3_LDADD = $(LDADD) $(LIBTHREAD)
-test_mbscasestr4_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbscasestr2_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
+test_mbscasestr3_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
+test_mbscasestr4_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbschr-tests b/modules/mbschr-tests
index f04e03c..33ee83f 100644
--- a/modules/mbschr-tests
+++ b/modules/mbschr-tests
@@ -15,4 +15,4 @@ Makefile.am:
TESTS += test-mbschr.sh
TESTS_ENVIRONMENT += LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-mbschr
-test_mbschr_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbschr_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbscspn-tests b/modules/mbscspn-tests
index a6eada1..8c4a3d1 100644
--- a/modules/mbscspn-tests
+++ b/modules/mbscspn-tests
@@ -15,4 +15,4 @@ Makefile.am:
TESTS += test-mbscspn.sh
TESTS_ENVIRONMENT += LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-mbscspn
-test_mbscspn_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbscspn_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbsinit-tests b/modules/mbsinit-tests
index e509efe..0674e9c 100644
--- a/modules/mbsinit-tests
+++ b/modules/mbsinit-tests
@@ -17,4 +17,4 @@ Makefile.am:
TESTS += test-mbsinit.sh
TESTS_ENVIRONMENT += LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-mbsinit
-test_mbsinit_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbsinit_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbsncasecmp-tests b/modules/mbsncasecmp-tests
index ad04325..050201a 100644
--- a/modules/mbsncasecmp-tests
+++ b/modules/mbsncasecmp-tests
@@ -15,4 +15,4 @@ Makefile.am:
TESTS += test-mbsncasecmp.sh
TESTS_ENVIRONMENT += LOCALE_TR_UTF8='@LOCALE_TR_UTF8@'
check_PROGRAMS += test-mbsncasecmp
-test_mbsncasecmp_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbsncasecmp_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbsnrtowcs-tests b/modules/mbsnrtowcs-tests
index ac67c85..4d90f17 100644
--- a/modules/mbsnrtowcs-tests
+++ b/modules/mbsnrtowcs-tests
@@ -31,4 +31,4 @@ TESTS_ENVIRONMENT += \
LOCALE_JA='@LOCALE_JA@' \
LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-mbsnrtowcs
-test_mbsnrtowcs_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbsnrtowcs_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbspbrk-tests b/modules/mbspbrk-tests
index 587ff5d..902e5b3 100644
--- a/modules/mbspbrk-tests
+++ b/modules/mbspbrk-tests
@@ -15,4 +15,4 @@ Makefile.am:
TESTS += test-mbspbrk.sh
TESTS_ENVIRONMENT += LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-mbspbrk
-test_mbspbrk_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbspbrk_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbspcasecmp-tests b/modules/mbspcasecmp-tests
index e1b87c3..e6f11ff 100644
--- a/modules/mbspcasecmp-tests
+++ b/modules/mbspcasecmp-tests
@@ -15,4 +15,4 @@ Makefile.am:
TESTS += test-mbspcasecmp.sh
TESTS_ENVIRONMENT += LOCALE_TR_UTF8='@LOCALE_TR_UTF8@'
check_PROGRAMS += test-mbspcasecmp
-test_mbspcasecmp_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbspcasecmp_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbsrchr-tests b/modules/mbsrchr-tests
index 326d566..1d97804 100644
--- a/modules/mbsrchr-tests
+++ b/modules/mbsrchr-tests
@@ -15,4 +15,4 @@ Makefile.am:
TESTS += test-mbsrchr.sh
TESTS_ENVIRONMENT += LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-mbsrchr
-test_mbsrchr_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbsrchr_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbsrtowcs-tests b/modules/mbsrtowcs-tests
index 24dfa3f..3de9d73 100644
--- a/modules/mbsrtowcs-tests
+++ b/modules/mbsrtowcs-tests
@@ -31,4 +31,4 @@ TESTS_ENVIRONMENT += \
LOCALE_JA='@LOCALE_JA@' \
LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-mbsrtowcs
-test_mbsrtowcs_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbsrtowcs_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbsspn-tests b/modules/mbsspn-tests
index 8a5fe23..994a706 100644
--- a/modules/mbsspn-tests
+++ b/modules/mbsspn-tests
@@ -15,4 +15,4 @@ Makefile.am:
TESTS += test-mbsspn.sh
TESTS_ENVIRONMENT += LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-mbsspn
-test_mbsspn_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbsspn_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/mbsstr-tests b/modules/mbsstr-tests
index a0a878b..739e51d 100644
--- a/modules/mbsstr-tests
+++ b/modules/mbsstr-tests
@@ -21,5 +21,5 @@ TESTS += test-mbsstr1 test-mbsstr2.sh test-mbsstr3.sh
TESTS_ENVIRONMENT += LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-mbsstr1 test-mbsstr2 test-mbsstr3
test_mbsstr1_LDADD = $(LDADD) $(LIBTHREAD)
-test_mbsstr2_LDADD = $(LDADD) $(LIBTHREAD)
-test_mbsstr3_LDADD = $(LDADD) $(LIBTHREAD)
+test_mbsstr2_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
+test_mbsstr3_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBTHREAD)
diff --git a/modules/nl_langinfo-tests b/modules/nl_langinfo-tests
index db0a57d..9474bbd 100644
--- a/modules/nl_langinfo-tests
+++ b/modules/nl_langinfo-tests
@@ -20,4 +20,4 @@ Makefile.am:
TESTS += test-nl_langinfo.sh test-nl_langinfo-mt
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-nl_langinfo test-nl_langinfo-mt
-test_nl_langinfo_mt_LDADD = $(LDADD) $(LIBMULTITHREAD) $(LIB_NANOSLEEP)
+test_nl_langinfo_mt_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBMULTITHREAD)
$(LIB_NANOSLEEP)
diff --git a/modules/quotearg-tests b/modules/quotearg-tests
index 61aa27c..486956a 100644
--- a/modules/quotearg-tests
+++ b/modules/quotearg-tests
@@ -27,4 +27,4 @@ Makefile.am:
TESTS += test-quotearg.sh
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-quotearg
-test_quotearg_LDADD = $(LDADD) @LIBINTL@ $(LIBTHREAD)
+test_quotearg_LDADD = $(LDADD) $(LIB_SETLOCALE) @LIBINTL@ $(LIBTHREAD)
diff --git a/modules/regex-tests b/modules/regex-tests
index 0782303..e8821ec 100644
--- a/modules/regex-tests
+++ b/modules/regex-tests
@@ -11,4 +11,4 @@ configure.ac:
Makefile.am:
TESTS += test-regex
check_PROGRAMS += test-regex
-test_regex_LDADD = $(LDADD) @LIBINTL@ $(LIBTHREAD)
+test_regex_LDADD = $(LDADD) $(LIB_SETLOCALE) @LIBINTL@ $(LIBTHREAD)
diff --git a/modules/setlocale b/modules/setlocale
index 5d5ed81..cc92e1a 100644
--- a/modules/setlocale
+++ b/modules/setlocale
@@ -7,7 +7,8 @@ m4/setlocale.m4
Depends-on:
locale
-localename [test $REPLACE_SETLOCALE = 1]
+localename [test $NEED_SETLOCALE_IMPROVED = 1]
+setlocale-null [test $NEED_SETLOCALE_MTSAFE = 1]
configure.ac:
gl_FUNC_SETLOCALE
@@ -22,6 +23,9 @@ Makefile.am:
Include:
<locale.h>
+Link:
+$(LIB_SETLOCALE)
+
License:
LGPL
diff --git a/modules/setlocale-tests b/modules/setlocale-tests
index 8c35c9d..25129f9 100644
--- a/modules/setlocale-tests
+++ b/modules/setlocale-tests
@@ -27,3 +27,5 @@ TESTS_ENVIRONMENT += \
LOCALE_JA='@LOCALE_JA@' \
LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-setlocale1 test-setlocale2
+test_setlocale1_LDADD = $(LDADD) @LIB_SETLOCALE@
+test_setlocale2_LDADD = $(LDADD) @LIB_SETLOCALE@
diff --git a/modules/strfmon_l-tests b/modules/strfmon_l-tests
index 871962c..cf2d6a2 100644
--- a/modules/strfmon_l-tests
+++ b/modules/strfmon_l-tests
@@ -10,3 +10,4 @@ configure.ac:
Makefile.am:
TESTS += test-strfmon_l
check_PROGRAMS += test-strfmon_l
+test_strfmon_l_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/strtod-tests b/modules/strtod-tests
index e3cd57f..0396658 100644
--- a/modules/strtod-tests
+++ b/modules/strtod-tests
@@ -26,3 +26,4 @@ TESTS_ENVIRONMENT += \
LOCALE_FR='@LOCALE_FR@' \
LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-strtod1
+test_strtod1_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/strtold-tests b/modules/strtold-tests
index c58e52c..dc82f50 100644
--- a/modules/strtold-tests
+++ b/modules/strtold-tests
@@ -26,3 +26,4 @@ TESTS_ENVIRONMENT += \
LOCALE_FR='@LOCALE_FR@' \
LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-strtold1
+test_strtold1_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/unicase/locale-language-tests
b/modules/unicase/locale-language-tests
index 2cf5926..1399e52 100644
--- a/modules/unicase/locale-language-tests
+++ b/modules/unicase/locale-language-tests
@@ -23,4 +23,4 @@ TESTS += unicase/test-locale-language.sh
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
LOCALE_JA='@LOCALE_JA@' LOCALE_TR_UTF8='@LOCALE_TR_UTF8@'
LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-locale-language
test_locale_language_SOURCES = unicase/test-locale-language.c
-test_locale_language_LDADD = $(LDADD) $(LIBUNISTRING) @INTL_MACOSX_LIBS@
$(LIBTHREAD)
+test_locale_language_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@INTL_MACOSX_LIBS@ $(LIBTHREAD)
diff --git a/modules/unicase/ulc-casecmp-tests
b/modules/unicase/ulc-casecmp-tests
index 0d78fbe..08a8620 100644
--- a/modules/unicase/ulc-casecmp-tests
+++ b/modules/unicase/ulc-casecmp-tests
@@ -22,5 +22,5 @@ TESTS_ENVIRONMENT += \
LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-ulc-casecmp
test_ulc_casecmp_SOURCES = unicase/test-ulc-casecmp.c
-test_ulc_casecmp_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
+test_ulc_casecmp_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING) @LIBICONV@
diff --git a/modules/unicase/ulc-casecoll-tests
b/modules/unicase/ulc-casecoll-tests
index bd2e59b..1610872 100644
--- a/modules/unicase/ulc-casecoll-tests
+++ b/modules/unicase/ulc-casecoll-tests
@@ -22,5 +22,5 @@ TESTS_ENVIRONMENT += \
LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-ulc-casecoll
test_ulc_casecoll_SOURCES = unicase/test-ulc-casecoll.c
-test_ulc_casecoll_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
+test_ulc_casecoll_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING) @LIBICONV@
diff --git a/modules/unigbrk/ulc-grapheme-breaks-tests
b/modules/unigbrk/ulc-grapheme-breaks-tests
index 187e26f..a6dacd0 100644
--- a/modules/unigbrk/ulc-grapheme-breaks-tests
+++ b/modules/unigbrk/ulc-grapheme-breaks-tests
@@ -16,4 +16,4 @@ TESTS += unigbrk/test-ulc-grapheme-breaks.sh
TESTS_ENVIRONMENT += LOCALE_AR='@LOCALE_AR@'
check_PROGRAMS += test-ulc-grapheme-breaks
test_ulc_grapheme_breaks_SOURCES = unigbrk/test-ulc-grapheme-breaks.c
-test_ulc_grapheme_breaks_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
+test_ulc_grapheme_breaks_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@LIBICONV@
diff --git a/modules/unistdio/u16-vasnprintf-tests
b/modules/unistdio/u16-vasnprintf-tests
index 3dc3cb0..45e3ab2 100644
--- a/modules/unistdio/u16-vasnprintf-tests
+++ b/modules/unistdio/u16-vasnprintf-tests
@@ -28,6 +28,6 @@ check_PROGRAMS += test-u16-vasnprintf1 test-u16-vasnprintf2
test-u16-vasnprintf3
test_u16_vasnprintf1_SOURCES = unistdio/test-u16-vasnprintf1.c
test_u16_vasnprintf1_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
test_u16_vasnprintf2_SOURCES = unistdio/test-u16-vasnprintf2.c
-test_u16_vasnprintf2_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
+test_u16_vasnprintf2_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@LIBICONV@
test_u16_vasnprintf3_SOURCES = unistdio/test-u16-vasnprintf3.c
-test_u16_vasnprintf3_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
+test_u16_vasnprintf3_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@LIBICONV@
diff --git a/modules/unistdio/u32-vasnprintf-tests
b/modules/unistdio/u32-vasnprintf-tests
index 555319b..7343c32 100644
--- a/modules/unistdio/u32-vasnprintf-tests
+++ b/modules/unistdio/u32-vasnprintf-tests
@@ -28,6 +28,6 @@ check_PROGRAMS += test-u32-vasnprintf1 test-u32-vasnprintf2
test-u32-vasnprintf3
test_u32_vasnprintf1_SOURCES = unistdio/test-u32-vasnprintf1.c
test_u32_vasnprintf1_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
test_u32_vasnprintf2_SOURCES = unistdio/test-u32-vasnprintf2.c
-test_u32_vasnprintf2_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
+test_u32_vasnprintf2_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@LIBICONV@
test_u32_vasnprintf3_SOURCES = unistdio/test-u32-vasnprintf3.c
-test_u32_vasnprintf3_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
+test_u32_vasnprintf3_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@LIBICONV@
diff --git a/modules/unistdio/u8-vasnprintf-tests
b/modules/unistdio/u8-vasnprintf-tests
index 8d5e295..70c9820 100644
--- a/modules/unistdio/u8-vasnprintf-tests
+++ b/modules/unistdio/u8-vasnprintf-tests
@@ -28,6 +28,6 @@ check_PROGRAMS += test-u8-vasnprintf1 test-u8-vasnprintf2
test-u8-vasnprintf3
test_u8_vasnprintf1_SOURCES = unistdio/test-u8-vasnprintf1.c
test_u8_vasnprintf1_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
test_u8_vasnprintf2_SOURCES = unistdio/test-u8-vasnprintf2.c
-test_u8_vasnprintf2_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
+test_u8_vasnprintf2_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@LIBICONV@
test_u8_vasnprintf3_SOURCES = unistdio/test-u8-vasnprintf3.c
-test_u8_vasnprintf3_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
+test_u8_vasnprintf3_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@LIBICONV@
diff --git a/modules/unistdio/ulc-vasnprintf-tests
b/modules/unistdio/ulc-vasnprintf-tests
index b72c188..0af2361 100644
--- a/modules/unistdio/ulc-vasnprintf-tests
+++ b/modules/unistdio/ulc-vasnprintf-tests
@@ -24,6 +24,6 @@ check_PROGRAMS += test-ulc-vasnprintf1 test-ulc-vasnprintf2
test-ulc-vasnprintf3
test_ulc_vasnprintf1_SOURCES = unistdio/test-ulc-vasnprintf1.c
test_ulc_vasnprintf1_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@ $(LIBTHREAD)
test_ulc_vasnprintf2_SOURCES = unistdio/test-ulc-vasnprintf2.c
-test_ulc_vasnprintf2_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@ $(LIBTHREAD)
+test_ulc_vasnprintf2_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@LIBICONV@ $(LIBTHREAD)
test_ulc_vasnprintf3_SOURCES = unistdio/test-ulc-vasnprintf3.c
-test_ulc_vasnprintf3_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@ $(LIBTHREAD)
+test_ulc_vasnprintf3_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@LIBICONV@ $(LIBTHREAD)
diff --git a/modules/uniwbrk/ulc-wordbreaks-tests
b/modules/uniwbrk/ulc-wordbreaks-tests
index 19f1ee6..cfb866b 100644
--- a/modules/uniwbrk/ulc-wordbreaks-tests
+++ b/modules/uniwbrk/ulc-wordbreaks-tests
@@ -16,5 +16,5 @@ TESTS += uniwbrk/test-ulc-wordbreaks.sh
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@'
check_PROGRAMS += test-ulc-wordbreaks
test_ulc_wordbreaks_SOURCES = uniwbrk/test-ulc-wordbreaks.c
-test_ulc_wordbreaks_LDADD = $(LDADD) $(LIBUNISTRING) @LIBICONV@
+test_ulc_wordbreaks_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
@LIBICONV@
diff --git a/modules/vasnprintf-posix-tests b/modules/vasnprintf-posix-tests
index 6ba745b..2ea2791 100644
--- a/modules/vasnprintf-posix-tests
+++ b/modules/vasnprintf-posix-tests
@@ -24,3 +24,5 @@ Makefile.am:
TESTS += test-vasnprintf-posix test-vasnprintf-posix2.sh test-vasnprintf-posix3
TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
check_PROGRAMS += test-vasnprintf-posix test-vasnprintf-posix2
test-vasnprintf-posix3
+test_vasnprintf_posix2_LDADD = $(LDADD) $(LIB_SETLOCALE)
+test_vasnprintf_posix3_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/wcrtomb-tests b/modules/wcrtomb-tests
index 32f9d3a..43c28e8 100644
--- a/modules/wcrtomb-tests
+++ b/modules/wcrtomb-tests
@@ -35,4 +35,4 @@ TESTS_ENVIRONMENT += \
LOCALE_JA='@LOCALE_JA@' \
LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-wcrtomb test-wcrtomb-w32
-
+test_wcrtomb_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/wcsnrtombs-tests b/modules/wcsnrtombs-tests
index 877dd17..adeda4e 100644
--- a/modules/wcsnrtombs-tests
+++ b/modules/wcsnrtombs-tests
@@ -28,4 +28,4 @@ TESTS_ENVIRONMENT += \
LOCALE_JA='@LOCALE_JA@' \
LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-wcsnrtombs
-
+test_wcsnrtombs_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/wcsrtombs-tests b/modules/wcsrtombs-tests
index 4b6bf54..2f52f68 100644
--- a/modules/wcsrtombs-tests
+++ b/modules/wcsrtombs-tests
@@ -28,4 +28,4 @@ TESTS_ENVIRONMENT += \
LOCALE_JA='@LOCALE_JA@' \
LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-wcsrtombs
-
+test_wcsrtombs_LDADD = $(LDADD) $(LIB_SETLOCALE)
diff --git a/modules/wcwidth-tests b/modules/wcwidth-tests
index 9606674..875d18f 100644
--- a/modules/wcwidth-tests
+++ b/modules/wcwidth-tests
@@ -12,4 +12,4 @@ configure.ac:
Makefile.am:
TESTS += test-wcwidth
check_PROGRAMS += test-wcwidth
-test_wcwidth_LDADD = $(LDADD) $(LIBUNISTRING)
+test_wcwidth_LDADD = $(LDADD) $(LIB_SETLOCALE) $(LIBUNISTRING)
diff --git a/tests/locale.c b/tests/locale.c
index ac587ad..52f50f8 100644
--- a/tests/locale.c
+++ b/tests/locale.c
@@ -22,6 +22,10 @@
#include <stdio.h>
#include <stdlib.h>
+/* We want to use the system's setlocale() function here, not the gnulib
+ override. */
+#undef setlocale
+
/* Specification:
<https://pubs.opengroup.org/onlinepubs/9699919799/utilities/locale.html>
Here we implement only the invocation without any command-line options. */
diff --git a/tests/test-setlocale_null-all.c b/tests/test-setlocale_null-all.c
index b3ebb13..45eb27e 100644
--- a/tests/test-setlocale_null-all.c
+++ b/tests/test-setlocale_null-all.c
@@ -28,6 +28,10 @@
#include "glthread/thread.h"
+/* We want to use the system's setlocale() function here, not the gnulib
+ override. */
+#undef setlocale
+
/* Some common locale names. */
diff --git a/tests/test-setlocale_null-one.c b/tests/test-setlocale_null-one.c
index 1aa5eaa..9e9bc12 100644
--- a/tests/test-setlocale_null-one.c
+++ b/tests/test-setlocale_null-one.c
@@ -28,6 +28,10 @@
#include "glthread/thread.h"
+/* We want to use the system's setlocale() function here, not the gnulib
+ override. */
+#undef setlocale
+
/* Some common locale names. */
- setlocale: make calls with NULL argument multithread-safe,
Bruno Haible <=