This is the mail archive of the
cygwin-developers
mailing list for the Cygwin project.
Re: bash and the current locale implementation
On Oct 1 19:34, Andy Koppe wrote:
> 2009/10/1 Corinna Vinschen
> > Ok, I have a small patch which changes the current implementation
> > so that a switch to another Cygwin-internal charset only works at
> > process startup. ?No setenv/setlocale combination from the application
> > itself will change the internally used charset.
> >
> > Basically that's what you see in bash already without the change.
> > export LANG=de will only have an effect on child processes.
> >
> > Is that now the feasible behaviour, finally?
>
> Fingers crossed ...
>
>
> > ? /* Set internal locale to the environment settings. */
> > - ?setlocale (LC_CTYPE, "");
> > + ?initial_setlocale ();
> > ? /* Reset application locale to "C" per POSIX */
> > ? _setlocale_r (_REENT, LC_CTYPE, "C");
>
> Does initial_setlocale() still need to save and possibly restore the
> old locale given that it's immediately followed by the _setlocale_r
> call?
Try this instead. initial_setlocale() now resets the locale to "C",
so there's only one call in dll_crt0_1(). setlocale() stores and
restores the old locale if necessary. Of course we can not revert to
newlib's setlocale. This time I even added comments (*gasp*) to
make clear what is supposed to happen.
Corinna
Index: dcrt0.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/dcrt0.cc,v
retrieving revision 1.363
diff -u -p -r1.363 dcrt0.cc
--- dcrt0.cc 28 Sep 2009 10:43:49 -0000 1.363
+++ dcrt0.cc 1 Oct 2009 19:12:43 -0000
@@ -762,6 +762,8 @@ dll_crt0_0 ()
void
dll_crt0_1 (void *)
{
+ extern void initial_setlocale ();
+
if (dynamically_loaded)
sigproc_init ();
check_sanity_and_sync (user_data);
@@ -940,9 +942,7 @@ dll_crt0_1 (void *)
LoadLibrary serialization. */
ld_preload ();
/* Set internal locale to the environment settings. */
- setlocale (LC_CTYPE, "");
- /* Reset application locale to "C" per POSIX */
- _setlocale_r (_REENT, LC_CTYPE, "C");
+ initial_setlocale ();
if (user_data->main)
cygwin_exit (user_data->main (__argc, __argv, *user_data->envptr));
__asm__ (" \n\
Index: syscalls.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v
retrieving revision 1.538
diff -u -p -r1.538 syscalls.cc
--- syscalls.cc 30 Sep 2009 02:11:05 -0000 1.538
+++ syscalls.cc 1 Oct 2009 19:12:44 -0000
@@ -4209,6 +4209,24 @@ internal_setlocale ()
setenv ("PATH", c_path, 1);
}
+/* Called from dll_crt0_1, before calling the application's main().
+ Set the internal charset according to the environment locale settings.
+ Check if a required codepage is available, and only switch internal
+ charset if so. Afterwards, reset application locale to "C" per POSIX. */
+void
+initial_setlocale ()
+{
+ char *ret = _setlocale_r (_REENT, LC_CTYPE, "");
+ if (ret && check_codepage (ret)
+ && strcmp (cygheap->locale.charset, __locale_charset ()) != 0)
+ internal_setlocale ();
+ _setlocale_r (_REENT, LC_CTYPE, "C");
+}
+
+/* Like newlib's setlocale, but additionally check if the charset needs
+ OS support and the required codepage is actually installed. If codepage
+ is not available, revert to previous locale and return NULL. For details
+ about codepage availability, see the comment in check_codepage() above. */
extern "C" char *
setlocale (int category, const char *locale)
{
@@ -4216,13 +4234,7 @@ setlocale (int category, const char *loc
if (locale && !wincap.has_always_all_codepages ())
stpcpy (old, _setlocale_r (_REENT, category, NULL));
char *ret = _setlocale_r (_REENT, category, locale);
- if (ret && locale)
- {
- if (!(ret = check_codepage (ret)))
- _setlocale_r (_REENT, category, old);
- else if (!*locale && strcmp (cygheap->locale.charset,
- __locale_charset ()) != 0)
- internal_setlocale ();
- }
+ if (ret && locale && !(ret = check_codepage (ret)))
+ _setlocale_r (_REENT, category, old);
return ret;
}
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat