bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
From: Bruno Haible <bruno@clisp.org>
To: bug-gnulib@gnu.org
Subject: wcrtomb: make multithread-safe
Date: Wed, 08 Jan 2020 03:57:11 +0100	[thread overview]
Message-ID: <2616981.55nkaXiEP9@omega> (raw)

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



                 reply	other threads:[~2020-01-08  2:57 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2616981.55nkaXiEP9@omega \
    --to=bruno@clisp.org \
    --cc=bug-gnulib@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).