* locale/setlocale.c (setlocale): Take the setlocale lock earlier.
authorUlrich Drepper <drepper@redhat.com>
Sun, 20 Jul 2008 08:49:18 +0000 (08:49 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 20 Jul 2008 08:49:18 +0000 (08:49 +0000)
ChangeLog
locale/setlocale.c
stdio-common/vfprintf.c

index 15b1c52..c90a2e8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-07-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * locale/setlocale.c (setlocale): Take the setlocale lock earlier.
+
 2008-07-15  Ulrich Drepper  <drepper@redhat.com>
 
        * stdio-common/vfprintf.c (_IO_helper_overflow): In case _IO_sputn
index 767a5aa..76cae82 100644 (file)
@@ -234,9 +234,16 @@ setlocale (int category, const char *locale)
   if (locale == NULL)
     return (char *) _nl_global_locale.__names[category];
 
+  /* Protect global data.  */
+  __libc_rwlock_wrlock (__libc_setlocale_lock);
+
   if (strcmp (locale, _nl_global_locale.__names[category]) == 0)
-    /* Changing to the same thing.  */
-    return (char *) _nl_global_locale.__names[category];
+    {
+      /* Changing to the same thing.  */
+      __libc_rwlock_unlock (__libc_setlocale_lock);
+
+      return (char *) _nl_global_locale.__names[category];
+    }
 
   /* We perhaps really have to load some data.  So we determine the
      path in which to look for the data now.  The environment variable
@@ -250,12 +257,13 @@ setlocale (int category, const char *locale)
   if (locpath_var != NULL && locpath_var[0] != '\0')
     {
       if (__argz_create_sep (locpath_var, ':',
-                            &locale_path, &locale_path_len) != 0)
-       return NULL;
-
-      if (__argz_add_sep (&locale_path, &locale_path_len,
-                         _nl_default_locale_path, ':') != 0)
-       return NULL;
+                            &locale_path, &locale_path_len) != 0
+         || __argz_add_sep (&locale_path, &locale_path_len,
+                            _nl_default_locale_path, ':') != 0)
+       {
+         __libc_rwlock_unlock (__libc_setlocale_lock);
+         return NULL;
+       }
     }
 
   if (category == LC_ALL)
@@ -290,8 +298,13 @@ setlocale (int category, const char *locale)
                  break;
 
              if (cnt == __LC_LAST)
-               /* Bogus category name.  */
-               ERROR_RETURN;
+               {
+               error_return:
+                 __libc_rwlock_unlock (__libc_setlocale_lock);
+
+                 /* Bogus category name.  */
+                 ERROR_RETURN;
+               }
 
              /* Found the category this clause sets.  */
              newnames[cnt] = ++cp;
@@ -310,12 +323,9 @@ setlocale (int category, const char *locale)
          for (cnt = 0; cnt < __LC_LAST; ++cnt)
            if (cnt != LC_ALL && newnames[cnt] == locale)
              /* The composite name did not specify all categories.  */
-             ERROR_RETURN;
+             goto error_return;
        }
 
-      /* Protect global data.  */
-      __libc_rwlock_wrlock (__libc_setlocale_lock);
-
       /* Load the new data for each category.  */
       while (category-- > 0)
        if (category != LC_ALL)
@@ -393,9 +403,6 @@ setlocale (int category, const char *locale)
       struct locale_data *newdata = NULL;
       const char *newname[1] = { locale };
 
-      /* Protect global data.  */
-      __libc_rwlock_wrlock (__libc_setlocale_lock);
-
       if (CATEGORY_USED (category))
        {
          /* Only actually load the data if anything will use it.  */
index 78a1c77..714c76c 100644 (file)
@@ -2080,8 +2080,11 @@ _IO_helper_overflow (_IO_FILE *s, int c)
     {
       _IO_size_t written = _IO_sputn (target, s->_wide_data->_IO_write_base,
                                      used);
-      if (written == 0)
+      if (written == 0 || written == WEOF)
        return WEOF;
+      __wmemmove (s->_wide_data->_IO_write_base,
+                 s->_wide_data->_IO_write_base + written,
+                 used - written);
       s->_wide_data->_IO_write_ptr -= written;
     }
 #else
@@ -2089,8 +2092,10 @@ _IO_helper_overflow (_IO_FILE *s, int c)
   if (used)
     {
       _IO_size_t written = _IO_sputn (target, s->_IO_write_base, used);
-      if (written == 0)
+      if (written == 0 || written == EOF)
        return EOF;
+      memmove (s->_IO_write_base, s->_IO_write_base + written,
+              used - written);
       s->_IO_write_ptr -= written;
     }
 #endif