]> Savannah Git Hosting - gnulib.git/commitdiff
duplocale: Fix multithread-safety bug on AIX.
authorBruno Haible <bruno@clisp.org>
Sun, 15 Dec 2019 22:07:28 +0000 (23:07 +0100)
committerBruno Haible <bruno@clisp.org>
Sun, 15 Dec 2019 22:44:03 +0000 (23:44 +0100)
* 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).

ChangeLog
lib/duplocale.c
m4/duplocale.m4
modules/duplocale
modules/duplocale-tests

index af1d5bf90367e36fa3836955ad546fbec679518a..4f46f01a4eac9d090e0674f2c17269905a6950f2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+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.
index 3b958bab510ffb23209b54b1bcb0325be0ef86a9..d22a447a912aae04e5ee56943eab5276066d0a27 100644 (file)
@@ -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;
     }
 
index fb5e602a09687f8dc5dbf5ccc2f193ca9a80022d..3900b53b5e88e03b9839f04c14decc662cb33836 100644 (file)
@@ -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.
index 08eca3c26196f341169f49ba23d92a6e28621688..aaa12cd09db889987d4f15cbeaf0811ba45bf16f 100644 (file)
@@ -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
 
index 29b2a1a02da5d9003f9084712846151ecede8d9b..6545c4e33aefbb7d3d1d997ab4bc7b3f048b89b4 100644 (file)
@@ -15,3 +15,4 @@ gt_FUNC_USELOCALE
 Makefile.am:
 TESTS += test-duplocale
 check_PROGRAMS += test-duplocale
+test_duplocale_LDADD = $(LDADD) @LIB_DUPLOCALE@