From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id EF7DD3858C33; Mon, 6 Feb 2023 15:06:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EF7DD3858C33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1675696015; bh=DD6b7l3H0i637pVlDuq7GzEoD0GNf7Ee9d6P8QdS7oA=; h=From:To:Subject:Date:From; b=vcZyuUhYkAG8scluKixoWNXSWMlYUNf0dZUIm4q4k8cyXAJN1nBvvPqAREpmySDNU hbrvMmCI9g99iQHbLO3RcNeFi5nyRlETASxxdZhzGgmNhlHst9ulcJm9ySKG9stS4A RByObJZdg1vIAHFlUZlE5ZXkZm5zAildjO0BhZlc= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Corinna Vinschen To: newlib-cvs@sourceware.org Subject: [newlib-cygwin/cygwin-3_4-branch] setlocale: create LC_ALL string when changing locale X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/cygwin-3_4-branch X-Git-Oldrev: 4384f47b93a1111bda31eb1570605a52a35730cc X-Git-Newrev: df34bd951d5cccdfee8ad6d1c658953305b5b684 Message-Id: <20230206150655.EF7DD3858C33@sourceware.org> Date: Mon, 6 Feb 2023 15:06:55 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3Ddf34bd951d5= cccdfee8ad6d1c658953305b5b684 commit df34bd951d5cccdfee8ad6d1c658953305b5b684 Author: Corinna Vinschen AuthorDate: Mon Feb 6 11:27:44 2023 +0100 Commit: Corinna Vinschen CommitDate: Mon Feb 6 16:05:57 2023 +0100 setlocale: create LC_ALL string when changing locale =20 This patch is for the sake of gnulib. =20 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. =20 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. =20 And here's the problem... =20 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. =20 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. =20 Signed-off-by: Corinna Vinschen 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 =3D /* 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)] + =3D "C"; static char *currentlocale (void); =20 #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; =20 if (category < LC_ALL || category >=3D _LC_LAST) { @@ -321,7 +323,7 @@ _setlocale_r (struct _reent *p, =20 if (locale =3D=3D NULL) return category !=3D LC_ALL ? __get_global_locale ()->categories[categ= ory] - : currentlocale(); + : global_locale_string; =20 /* * Default to the current locale for everything. @@ -415,8 +417,12 @@ _setlocale_r (struct _reent *p, } =20 if (category !=3D LC_ALL) - return __loadlocale (__get_global_locale (), category, - new_categories[category]); + { + ret =3D __loadlocale (__get_global_locale (), category, + new_categories[category]); + currentlocale (); + return ret; + } =20 for (i =3D 1; i < _LC_LAST; ++i) {