diff options
Diffstat (limited to 'cygwin')
-rw-r--r-- | cygwin/cygwin.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/cygwin/cygwin.c b/cygwin/cygwin.c index 59aa730448..24b278f2fd 100644 --- a/cygwin/cygwin.c +++ b/cygwin/cygwin.c @@ -154,7 +154,15 @@ wide_to_utf8(const wchar_t *wbuf) { char *buf; int wlen = 0; - char *oldlocale = setlocale(LC_CTYPE, NULL); + char *oldlocale; + dVAR; + + /* Here and elsewhere in this file, we have a critical section to prevent + * another thread from changing the locale out from under us. XXX But why + * not just use uvchr_to_utf8? */ + LOCALE_LOCK; + + oldlocale = setlocale(LC_CTYPE, NULL); setlocale(LC_CTYPE, "utf-8"); /* uvchr_to_utf8(buf, chr) or Encoding::_bytes_to_utf8(sv, "UCS-2BE"); */ @@ -164,6 +172,9 @@ wide_to_utf8(const wchar_t *wbuf) if (oldlocale) setlocale(LC_CTYPE, oldlocale); else setlocale(LC_CTYPE, "C"); + + LOCALE_UNLOCK; + return buf; } @@ -172,8 +183,13 @@ utf8_to_wide(const char *buf) { wchar_t *wbuf; mbstate_t mbs; - char *oldlocale = setlocale(LC_CTYPE, NULL); + char *oldlocale; int wlen = sizeof(wchar_t)*strlen(buf); + dVAR; + + LOCALE_LOCK; + + oldlocale = setlocale(LC_CTYPE, NULL); setlocale(LC_CTYPE, "utf-8"); wbuf = (wchar_t *) safemalloc(wlen); @@ -182,6 +198,9 @@ utf8_to_wide(const char *buf) if (oldlocale) setlocale(LC_CTYPE, oldlocale); else setlocale(LC_CTYPE, "C"); + + LOCALE_UNLOCK; + return wbuf; } #endif /* cygwin 1.7 */ @@ -280,7 +299,12 @@ XS(XS_Cygwin_win_to_posix_path) wchar_t *wbuf = (wchar_t *) safemalloc(wlen); if (!IN_BYTES) { mbstate_t mbs; - char *oldlocale = setlocale(LC_CTYPE, NULL); + char *oldlocale; + dVAR; + + LOCALE_LOCK; + + oldlocale = setlocale(LC_CTYPE, NULL); setlocale(LC_CTYPE, "utf-8"); /* utf8_to_uvchr_buf(src_path, src_path + wlen, wpath) or Encoding::_utf8_to_bytes(sv, "UCS-2BE"); */ wlen = mbsrtowcs(wpath, (const char**)&src_path, wlen, &mbs); @@ -288,6 +312,8 @@ XS(XS_Cygwin_win_to_posix_path) err = cygwin_conv_path(what, wpath, wbuf, wlen); if (oldlocale) setlocale(LC_CTYPE, oldlocale); else setlocale(LC_CTYPE, "C"); + + LOCALE_UNLOCK; } else { /* use bytes; assume already ucs-2 encoded bytestream */ err = cygwin_conv_path(what, src_path, wbuf, wlen); } @@ -365,7 +391,12 @@ XS(XS_Cygwin_posix_to_win_path) int wlen = sizeof(wchar_t)*(len + 260 + 1001); wchar_t *wpath = (wchar_t *) safemalloc(sizeof(wchar_t)*len); wchar_t *wbuf = (wchar_t *) safemalloc(wlen); - char *oldlocale = setlocale(LC_CTYPE, NULL); + char *oldlocale; + dVAR; + + LOCALE_LOCK; + + oldlocale = setlocale(LC_CTYPE, NULL); setlocale(LC_CTYPE, "utf-8"); if (!IN_BYTES) { mbstate_t mbs; @@ -388,6 +419,8 @@ XS(XS_Cygwin_posix_to_win_path) wcsrtombs(win_path, (const wchar_t **)&wbuf, wlen, NULL); if (oldlocale) setlocale(LC_CTYPE, oldlocale); else setlocale(LC_CTYPE, "C"); + + LOCALE_UNLOCK; } else { int what = absolute_flag ? CCP_POSIX_TO_WIN_A : CCP_POSIX_TO_WIN_A | CCP_RELATIVE; win_path = (char *) safemalloc(len + 260 + 1001); |