diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | locale/setlocale.c | 41 | ||||
-rw-r--r-- | stdio-common/vfprintf.c | 9 |
3 files changed, 35 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog index 15b1c5284f..c90a2e8099 100644 --- 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 diff --git a/locale/setlocale.c b/locale/setlocale.c index 767a5aab6b..76cae82a72 100644 --- a/locale/setlocale.c +++ b/locale/setlocale.c @@ -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. */ diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index 78a1c77d8a..714c76c3d4 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -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 |