public inbox for newlib-cvs@sourceware.org
help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org>
To: newlib-cvs@sourceware.org
Subject: [newlib-cygwin/cygwin-3_4-branch] setlocale: create LC_ALL string when changing locale
Date: Mon,  6 Feb 2023 15:06:55 +0000 (GMT)	[thread overview]
Message-ID: <20230206150655.EF7DD3858C33@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=df34bd951d5cccdfee8ad6d1c658953305b5b684

commit df34bd951d5cccdfee8ad6d1c658953305b5b684
Author:     Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Mon Feb 6 11:27:44 2023 +0100
Commit:     Corinna Vinschen <corinna@vinschen.de>
CommitDate: Mon Feb 6 16:05:57 2023 +0100

    setlocale: create LC_ALL string when changing locale
    
    This patch is for the sake of gnulib.
    
    gnulib implements some form of a thread-safe setlocale variant
    called setlocale_null_r, which is supposed to return the locale
    strings in a thread-safe manner.  This only succeeds if the system's
    setlocale already handles this thread-safe, otherwise gnulib adds
    some locking on its own.
    
    Newlib's setlocale always writes the global string array holding the
    LC_ALL value anew on each invocation of setlocale(LC_ALL, NULL).
    Since that doesn't allow to call setlocale(LC_ALL, NULL) in a
    thread-safe manner, so locking in gnulib is required.
    
    And here's the problem...
    
    The lock is decorated as dllexport when building for Cygwin.  This
    collides with the default behaviour of ld to export all symbols.
    If it finds one decorated symbol, it will only export this symbol
    to the DLL import lib.
    
    Change setlocale so that it writes the global string array
    holding the LC_ALL value at the time the locale gets changed.
    On setlocale(LC_ALL, NULL), just return the pointer to the
    global LC_ALL string array, just as in GLibc.  The burden of
    doing so is negligibly for all targets, but adds thread-safety
    for gnulib's setlocal_null_r() function, and gnulib can drop
    the lock entirely when building for Cygwin.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 newlib/libc/locale/locale.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c
index 65e2b1833e5e..b0f6314ff49b 100644
--- a/newlib/libc/locale/locale.c
+++ b/newlib/libc/locale/locale.c
@@ -289,7 +289,8 @@ struct __locale_t __global_locale =
 /* Renamed from current_locale_string to make clear this is only the
    *global* string for setlocale (LC_ALL, NULL).  There's no equivalent
    functionality for uselocale. */
-static char global_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)];
+static char global_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)]
+	    = "C";
 static char *currentlocale (void);
 
 #endif /* _MB_CAPABLE */
@@ -312,6 +313,7 @@ _setlocale_r (struct _reent *p,
   static char saved_categories[_LC_LAST][ENCODING_LEN + 1];
   int i, j, len, saverr;
   const char *env, *r;
+  char *ret;
 
   if (category < LC_ALL || category >= _LC_LAST)
     {
@@ -321,7 +323,7 @@ _setlocale_r (struct _reent *p,
 
   if (locale == NULL)
     return category != LC_ALL ? __get_global_locale ()->categories[category]
-			      : currentlocale();
+			      : global_locale_string;
 
   /*
    * Default to the current locale for everything.
@@ -415,8 +417,12 @@ _setlocale_r (struct _reent *p,
     }
 
   if (category != LC_ALL)
-    return __loadlocale (__get_global_locale (), category,
-			 new_categories[category]);
+    {
+      ret = __loadlocale (__get_global_locale (), category,
+			  new_categories[category]);
+      currentlocale ();
+      return ret;
+    }
 
   for (i = 1; i < _LC_LAST; ++i)
     {

                 reply	other threads:[~2023-02-06 15:06 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

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

  git send-email \
    --in-reply-to=20230206150655.EF7DD3858C33@sourceware.org \
    --to=corinna@sourceware.org \
    --cc=newlib-cvs@sourceware.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).