This is the mail archive of the cygwin-developers mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]