aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-05-13 15:00:06 +0000
committerCorinna Vinschen <corinna@vinschen.de>2009-05-13 15:00:06 +0000
commitb6c6ea43f30ee958ca1f0af950af01f683f7b5c9 (patch)
tree16b5a88b3b3ae4bad7bbe8747a6873b7a9ed2c02
parent136033a8528352fb63fd25534de9fc10173a2576 (diff)
downloadnewlib-b6c6ea43f30ee958ca1f0af950af01f683f7b5c9.zip
newlib-b6c6ea43f30ee958ca1f0af950af01f683f7b5c9.tar.gz
newlib-b6c6ea43f30ee958ca1f0af950af01f683f7b5c9.tar.bz2
* cygheap.h (cwdstuff): Convert to class. Make posix and dir private.
(cwdstuff::get_posix): New method. (cwdstuff::reset_posix): New method. * dcrt0.cc (dll_crt0_1): Call setlocale rather than _setlocale_r. * environ.cc (environ_init): Ditto. Prefer "C" locale over current codepage default locale. * path.cc (chdir): Use cwdstuff::get_posix method instead of accessing cwdstuff::posix directly. (cwdstuff::set): Defer creating posix path to first usage. (cwdstuff::get_posix): Create posix path if it's empty, and return it. (cwdstuff::get): Create posix path if it's empty. * strfuncs.cc (sys_cp_wcstombs): Use UTF-8 conversion in the "C" locale. (sys_cp_mbstowcs): Ditto. * syscalls.cc (gen_full_path_at): Fetch CWD posix path locked. (setlocale): Implement here. Reset CWD posix path.
-rw-r--r--winsup/cygwin/ChangeLog19
-rw-r--r--winsup/cygwin/cygheap.h8
-rw-r--r--winsup/cygwin/dcrt0.cc2
-rw-r--r--winsup/cygwin/environ.cc5
-rw-r--r--winsup/cygwin/path.cc28
-rw-r--r--winsup/cygwin/strfuncs.cc4
-rw-r--r--winsup/cygwin/syscalls.cc20
7 files changed, 75 insertions, 11 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 0390de4..8691969 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,22 @@
+2009-05-13 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygheap.h (cwdstuff): Convert to class. Make posix and dir private.
+ (cwdstuff::get_posix): New method.
+ (cwdstuff::reset_posix): New method.
+ * dcrt0.cc (dll_crt0_1): Call setlocale rather than _setlocale_r.
+ * environ.cc (environ_init): Ditto. Prefer "C" locale over current
+ codepage default locale.
+ * path.cc (chdir): Use cwdstuff::get_posix method instead of accessing
+ cwdstuff::posix directly.
+ (cwdstuff::set): Defer creating posix path to first usage.
+ (cwdstuff::get_posix): Create posix path if it's empty, and return it.
+ (cwdstuff::get): Create posix path if it's empty.
+ * strfuncs.cc (sys_cp_wcstombs): Use UTF-8 conversion in the "C"
+ locale.
+ (sys_cp_mbstowcs): Ditto.
+ * syscalls.cc (gen_full_path_at): Fetch CWD posix path locked.
+ (setlocale): Implement here. Reset CWD posix path.
+
2009-05-09 Christopher Faylor <me+cygwin@cgf.cx>
* cygwin/version.h (CYGWIN_VERSION_CYGWIN_CONV): New define.
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index fe2333c..0932f86 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -225,13 +225,17 @@ public:
class muto;
-struct cwdstuff
+class cwdstuff
{
+private:
char *posix;
- UNICODE_STRING win32;
HANDLE dir;
+public:
+ UNICODE_STRING win32;
DWORD drive_length;
static muto cwd_lock;
+ char *get_posix ();
+ void reset_posix () { if (posix) posix[0] = '\0'; }
char *get (char *, int = 1, int = 0, unsigned = NT_MAX_PATH);
HANDLE get_handle () { return dir; }
DWORD get_drive (char * dst)
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 90960af..12365b7 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -931,7 +931,7 @@ dll_crt0_1 (void *)
LoadLibrary serialization. */
ld_preload ();
/* Reset current locale to "C" per POSIX */
- _setlocale_r (_GLOBAL_REENT, LC_CTYPE, "C");
+ setlocale (LC_CTYPE, "C");
if (user_data->main)
cygwin_exit (user_data->main (__argc, __argv, *user_data->envptr));
__asm__ (" \n\
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 8124e68..161b9d9 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -790,16 +790,13 @@ environ_init (char **envp, int envc)
{
char *buf = (char *) alloca (i);
GetEnvironmentVariableA (lc_arr[lc], buf, i);
- if (_setlocale_r (_GLOBAL_REENT, LC_CTYPE, buf))
+ if (setlocale (LC_CTYPE, buf))
{
got_lc = true;
break;
}
}
}
- /* No matching POSIX environment variable, use current codepage. */
- if (!got_lc)
- _setlocale_r (_GLOBAL_REENT, LC_CTYPE, "en_US");
/* We also need the CYGWIN variable early to know the value of the
CYGWIN=upcaseenv setting for the below loop. */
if ((i = GetEnvironmentVariableA ("CYGWIN", NULL, 0)))
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index ec5c40b..ca2df58 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2599,7 +2599,7 @@ chdir (const char *in_dir)
/* Note that we're accessing cwd.posix without a lock here. I didn't think
it was worth locking just for strace. */
syscall_printf ("%d = chdir() cygheap->cwd.posix '%s' native '%S'", res,
- cygheap->cwd.posix, path.get_nt_native_path ());
+ cygheap->cwd.get_posix (), path.get_nt_native_path ());
MALLOC_CHECK;
return res;
}
@@ -3230,8 +3230,8 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
posix_cwd = (const char *) tp.c_get ();
mount_table->conv_to_posix_path (win32.Buffer, (char *) posix_cwd, 0);
}
- posix = (char *) crealloc_abort (posix, strlen (posix_cwd) + 1);
- stpcpy (posix, posix_cwd);
+ if (posix)
+ posix[0] = '\0';
}
out:
@@ -3241,6 +3241,21 @@ out:
/* Copy the value for either the posix or the win32 cwd into a buffer. */
char *
+cwdstuff::get_posix ()
+{
+ if (!posix || !*posix)
+ {
+ tmp_pathbuf tp;
+
+ char *tocopy = tp.c_get ();
+ mount_table->conv_to_posix_path (win32.Buffer, tocopy, 0);
+ posix = (char *) crealloc_abort (posix, strlen (tocopy) + 1);
+ stpcpy (posix, tocopy);
+ }
+ return posix;
+}
+
+char *
cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
{
MALLOC_CHECK;
@@ -3265,6 +3280,13 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
sys_wcstombs (tocopy, NT_MAX_PATH, win32.Buffer,
win32.Length / sizeof (WCHAR));
}
+ else if (!posix || !*posix)
+ {
+ tocopy = tp.c_get ();
+ mount_table->conv_to_posix_path (win32.Buffer, tocopy, 0);
+ posix = (char *) crealloc_abort (posix, strlen (tocopy) + 1);
+ stpcpy (posix, tocopy);
+ }
else
tocopy = posix;
diff --git a/winsup/cygwin/strfuncs.cc b/winsup/cygwin/strfuncs.cc
index e039574..150f51f 100644
--- a/winsup/cygwin/strfuncs.cc
+++ b/winsup/cygwin/strfuncs.cc
@@ -418,6 +418,8 @@ sys_cp_wcstombs (wctomb_p f_wctomb, char *charset, char *dst, size_t len,
mbstate_t ps;
save_errno save;
+ if (f_wctomb == __ascii_wctomb)
+ f_wctomb = __utf8_wctomb;
memset (&ps, 0, sizeof ps);
if (dst == NULL)
len = (size_t) -1;
@@ -525,6 +527,8 @@ sys_cp_mbstowcs (mbtowc_p f_mbtowc, char *charset, wchar_t *dst, size_t dlen,
mbstate_t ps;
save_errno save;
+ if (f_mbtowc == __ascii_mbtowc)
+ f_mbtowc = __utf8_mbtowc;
memset (&ps, 0, sizeof ps);
if (dst == NULL)
len = (size_t)-1;
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 64c2534..ab31922 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -35,6 +35,7 @@ details. */
#include <utmpx.h>
#include <sys/uio.h>
#include <ctype.h>
+#include <locale.h>
#include <unistd.h>
#include <sys/wait.h>
#include <rpc.h>
@@ -3726,7 +3727,11 @@ gen_full_path_at (char *path_ret, int dirfd, const char *pathname,
char *p;
if (dirfd == AT_FDCWD)
- p = stpcpy (path_ret, cygheap->cwd.posix);
+ {
+ cwdstuff::cwd_lock.acquire ();
+ p = stpcpy (path_ret, cygheap->cwd.get_posix ());
+ cwdstuff::cwd_lock.release ();
+ }
else
{
cygheap_fdget cfd (dirfd);
@@ -4000,3 +4005,16 @@ unlinkat (int dirfd, const char *pathname, int flags)
return -1;
return (flags & AT_REMOVEDIR) ? rmdir (path) : unlink (path);
}
+
+extern "C" char *
+setlocale (int category, const char *locale)
+{
+ /* Each setlocale potentially changes the multibyte representation
+ of the CWD. Therefore we have to rest the CWD's posix path and
+ reevaluate the next time it's used. */
+ /* FIXME: Other buffered paths might be affected as well. */
+ char *ret = _setlocale_r (_REENT, category, locale);
+ if (ret)
+ cygheap->cwd.reset_posix ();
+ return ret;
+}