bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* wcrtomb: make multithread-safe
@ 2020-01-08  2:57 Bruno Haible
  0 siblings, 0 replies; only message in thread
From: Bruno Haible @ 2020-01-08  2:57 UTC (permalink / raw)
  To: bug-gnulib

The wcrtomb override is using wctomb(), which is not guaranteed to be
multithread-safe. Better use the original wcrtomb when possible.

It's not possible on IRIX, but I don't want to invest much effort into
this platform now.

Tested on the relevant platforms: 32-bit AIX, HP-UX, IRIX, Solaris 11.3,
MSVC, Android.


2020-01-07  Bruno Haible  <bruno@clisp.org>

	wcrtomb: Make multithread-safe, except possibly on IRIX.
	* m4/wcrtomb.m4 (gl_FUNC_WCRTOMB): Don't set REPLACE_WCRTOMB to 1 when
	REPLACE_MBSTATE_T is set. Define WCRTOMB_C_LOCALE_BUG and
	WCRTOMB_RETVAL_BUG.
	* lib/wcrtomb.c (wcrtomb): Use original wcrtomb whenever available. Use
	wctomb only on IRIX.

diff --git a/lib/wcrtomb.c b/lib/wcrtomb.c
index 63d0860..06105f1 100644
--- a/lib/wcrtomb.c
+++ b/lib/wcrtomb.c
@@ -26,6 +26,7 @@
 
 size_t
 wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
+#undef wcrtomb
 {
   /* This implementation of wcrtomb supports only stateless encodings.
      ps must be in the initial state.  */
@@ -35,12 +36,17 @@ wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
       return (size_t)(-1);
     }
 
+#if !HAVE_WCRTOMB                       /* IRIX 6.5 */ \
+    || WCRTOMB_RETVAL_BUG               /* Solaris 11.3, MSVC */ \
+    || WCRTOMB_C_LOCALE_BUG             /* Android */
   if (s == NULL)
     /* We know the NUL wide character corresponds to the NUL character.  */
     return 1;
   else
+#endif
     {
-#if defined __ANDROID__
+#if HAVE_WCRTOMB
+# if WCRTOMB_C_LOCALE_BUG               /* Android */
       /* Implement consistently with mbrtowc(): through a 1:1 correspondence,
          as in ISO-8859-1.  */
       if (wc >= 0 && wc <= 0xff)
@@ -48,17 +54,27 @@ wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
           *s = (unsigned char) wc;
           return 1;
         }
-#else
-      /* Implement on top of wctomb().  */
+      else
+        {
+          errno = EILSEQ;
+          return (size_t)(-1);
+        }
+# else
+      return wcrtomb (s, wc, ps);
+# endif
+#else                                   /* IRIX 6.5 */
+      /* Fallback for platforms that don't have wcrtomb().
+         Implement on top of wctomb().
+         This code is not multithread-safe.  */
       int ret = wctomb (s, wc);
 
       if (ret >= 0)
         return ret;
-#endif
       else
         {
           errno = EILSEQ;
           return (size_t)(-1);
         }
+#endif
     }
 }
diff --git a/m4/wcrtomb.m4 b/m4/wcrtomb.m4
index 64e5110..c45fd98 100644
--- a/m4/wcrtomb.m4
+++ b/m4/wcrtomb.m4
@@ -1,4 +1,4 @@
-# wcrtomb.m4 serial 15
+# wcrtomb.m4 serial 16
 dnl Copyright (C) 2008-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -31,9 +31,11 @@ AC_DEFUN([gl_FUNC_WCRTOMB],
       REPLACE_WCRTOMB=1
     fi
   else
-    if test $REPLACE_MBSTATE_T = 1; then
-      REPLACE_WCRTOMB=1
-    fi
+    dnl We don't actually need to override wcrtomb when redefining the semantics
+    dnl of the mbstate_t type. Tested on 32-bit AIX.
+    dnl if test $REPLACE_MBSTATE_T = 1; then
+    dnl   REPLACE_WCRTOMB=1
+    dnl fi
     if test $REPLACE_WCRTOMB = 0; then
       dnl On Android 4.3, wcrtomb produces wrong characters in the C locale.
       dnl On AIX 4.3, OSF/1 5.1 and Solaris <= 11.3, wcrtomb (NULL, 0, NULL)
@@ -79,7 +81,9 @@ int main ()
         ])
       case "$gl_cv_func_wcrtomb_works" in
         *yes) ;;
-        *) REPLACE_WCRTOMB=1 ;;
+        *) AC_DEFINE([WCRTOMB_C_LOCALE_BUG], [1],
+             [Define if the wcrtomb function does not work in the C locale.])
+           REPLACE_WCRTOMB=1 ;;
       esac
     fi
     if test $REPLACE_WCRTOMB = 0; then
@@ -148,7 +152,9 @@ int main ()
         ])
       case "$gl_cv_func_wcrtomb_retval" in
         *yes) ;;
-        *) REPLACE_WCRTOMB=1 ;;
+        *) AC_DEFINE([WCRTOMB_RETVAL_BUG], [1],
+             [Define if the wcrtomb function has an incorrect return value.])
+           REPLACE_WCRTOMB=1 ;;
       esac
     fi
   fi



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-01-08  2:57 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-08  2:57 wcrtomb: make multithread-safe Bruno Haible

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).