summaryrefslogtreecommitdiff
path: root/cygwin
diff options
context:
space:
mode:
Diffstat (limited to 'cygwin')
-rw-r--r--cygwin/cygwin.c41
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);