On AIX 7.2 with xlclang, the duplocale test fails. The reason is that setlocale's return value is overwritten by subsequent setlocale calls. The fix is to copy this value to the heap before doing the subsequent setlocale calls.
2019-12-12 Bruno Haible <br...@clisp.org> duplocale: Fix test failure on AIX 7.2 with xlclang. * lib/duplocale.c: Include <stdlib.h>. (rpl_duplocale): Use a heap-allocated copy of the first setlocale return value. diff --git a/lib/duplocale.c b/lib/duplocale.c index eaecf8c..3b958ba 100644 --- a/lib/duplocale.c +++ b/lib/duplocale.c @@ -22,6 +22,7 @@ #include <locale.h> #include <errno.h> +#include <stdlib.h> #include <string.h> #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) @@ -67,14 +68,21 @@ rpl_duplocale (locale_t locale) , { LC_IDENTIFICATION, LC_IDENTIFICATION_MASK } #endif }; - const char *base_name; + char *base_name; locale_t base_copy; unsigned int i; - base_name = setlocale (LC_CTYPE, NULL); + 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) - return NULL; + { + int saved_errno = errno; + free (base_name); + errno = saved_errno; + return NULL; + } for (i = 0; i < SIZEOF (categories); i++) { @@ -88,6 +96,7 @@ rpl_duplocale (locale_t locale) { int saved_errno = errno; freelocale (base_copy); + free (base_name); errno = saved_errno; return NULL; } @@ -97,6 +106,7 @@ rpl_duplocale (locale_t locale) } } + free (base_name); return base_copy; }