From: corinna Date: Thu, 1 Apr 2010 20:13:22 +0000 (+0000) Subject: * nlsfuncs.cc (rebase_locale_buf): New helper function to rebase X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=c7921d3c85d7732cd858b0e09f7cfaab2ec36518;p=pf3gnuchains%2Fpf3gnuchains4x.git * nlsfuncs.cc (rebase_locale_buf): New helper function to rebase function pointers in locale structures. Explain why this is necessary. (__set_lc_time_from_win): Use rebase_locale_buf after realloc. (__set_lc_numeric_from_win): Ditto. (__set_lc_monetary_from_win): Ditto. --- diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 734001f8e1..1ff7e24021 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,11 @@ +2010-04-01 Corinna Vinschen + + * nlsfuncs.cc (rebase_locale_buf): New helper function to rebase + function pointers in locale structures. Explain why this is necessary. + (__set_lc_time_from_win): Use rebase_locale_buf after realloc. + (__set_lc_numeric_from_win): Ditto. + (__set_lc_monetary_from_win): Ditto. + 2010-03-31 Christopher Faylor * sigproc.cc (wait_sig): Make sure that strace is activated on diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc index 3f2279a189..ddf6d14da8 100644 --- a/winsup/cygwin/nlsfuncs.cc +++ b/winsup/cygwin/nlsfuncs.cc @@ -325,6 +325,21 @@ locale_cmp (const void *a, const void *b) return strcmp (*la, *lb); } +/* Helper function to workaround reallocs which move blocks even if they shrink. + Cygwin's realloc is not doing this, but tcsh's, for instance. All lc_foo + structures consist entirely of pointers so they are practically pointer + arrays. What we do here is just treat the lc_foo pointers as char ** and + rebase all char * pointers within, up to the given size of the structure. */ +static void +rebase_locale_buf (const void *ptrv, const char *newbase, const char *oldbase, + const void *ptrvend) +{ + const char **ptrs = (const char **) ptrv; + const char **ptrsend = (const char **) ptrvend; + while (ptrs < ptrsend) + *ptrs++ += newbase - oldbase; +} + static char * __getlocaleinfo (LCID lcid, LCTYPE type, char **ptr, size_t size, wctomb_p f_wctomb, const char *charset) @@ -625,6 +640,9 @@ __set_lc_time_from_win (const char *name, struct lc_time_T *_time_locale, era = NULL; else { + if (tmp != new_lc_time_buf) + rebase_locale_buf (_time_locale, tmp, new_lc_time_buf, + _time_locale + 1); lc_time_ptr = tmp + (lc_time_ptr - new_lc_time_buf); new_lc_time_buf = tmp; lc_time_end = new_lc_time_buf + len; @@ -674,6 +692,9 @@ __set_lc_time_from_win (const char *name, struct lc_time_T *_time_locale, free (new_lc_time_buf); return -1; } + if (tmp != new_lc_time_buf) + rebase_locale_buf (_time_locale, tmp, new_lc_time_buf, + _time_locale + 1); if (*lc_time_buf) free (*lc_time_buf); *lc_time_buf = tmp; @@ -717,6 +738,9 @@ __set_lc_numeric_from_win (const char *name, free (new_lc_numeric_buf); return -1; } + if (tmp != new_lc_numeric_buf) + rebase_locale_buf (_numeric_locale, tmp, new_lc_numeric_buf, + _numeric_locale + 1); if (*lc_numeric_buf) free (*lc_numeric_buf); *lc_numeric_buf = tmp; @@ -816,6 +840,9 @@ __set_lc_monetary_from_win (const char *name, free (new_lc_monetary_buf); return -1; } + if (tmp != new_lc_monetary_buf) + rebase_locale_buf (_monetary_locale, tmp, new_lc_monetary_buf, + _monetary_locale + 1); if (*lc_monetary_buf) free (*lc_monetary_buf); *lc_monetary_buf = tmp;