summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-09-21 19:29:16 +0000
committerCorinna Vinschen <corinna@vinschen.de>2009-09-21 19:29:16 +0000
commitee42ccd3a2c71ddf73a7b58cdf7ce8afdd0da5dd (patch)
treeae7ba1374266f5e3060a65a0c66a6766de54319a
parent92763ad9ba0498994c6d466c7e58ba755560183a (diff)
downloadcygnal-ee42ccd3a2c71ddf73a7b58cdf7ce8afdd0da5dd.tar.gz
cygnal-ee42ccd3a2c71ddf73a7b58cdf7ce8afdd0da5dd.tar.bz2
cygnal-ee42ccd3a2c71ddf73a7b58cdf7ce8afdd0da5dd.zip
* cygheap.h (cwdstuff::get_posix): Convert to const inline method just
returning pointer to posix path. (cwdstuff::reset_posix): Convert to non-inline method taking a wchar_t pointer. * path.cc (cwdstuff::set): Revert change from 2009-05-13. Set posix to valid incoming path again. (cwdstuff::reset_posix): New implementation setting posix path from incoming wchar_t path. Explain usage. (cwdstuff::get_posix): Drop implementation. (cwdstuff::get): Drop special case to handle empty posix path. * syscalls.cc (internal_setlocale): Store old posix cwd as wide char path. Restore posix cwd using new charset. Explain why.
-rw-r--r--winsup/cygwin/ChangeLog15
-rw-r--r--winsup/cygwin/cygheap.h4
-rw-r--r--winsup/cygwin/path.cc31
-rw-r--r--winsup/cygwin/syscalls.cc19
4 files changed, 40 insertions, 29 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index bcd823f60..082c420e4 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,20 @@
2009-09-21 Corinna Vinschen <corinna@vinschen.de>
+ * cygheap.h (cwdstuff::get_posix): Convert to const inline method just
+ returning pointer to posix path.
+ (cwdstuff::reset_posix): Convert to non-inline method taking a wchar_t
+ pointer.
+ * path.cc (cwdstuff::set): Revert change from 2009-05-13. Set posix
+ to valid incoming path again.
+ (cwdstuff::reset_posix): New implementation setting posix path from
+ incoming wchar_t path. Explain usage.
+ (cwdstuff::get_posix): Drop implementation.
+ (cwdstuff::get): Drop special case to handle empty posix path.
+ * syscalls.cc (internal_setlocale): Store old posix cwd as wide char
+ path. Restore posix cwd using new charset. Explain why.
+
+2009-09-21 Corinna Vinschen <corinna@vinschen.de>
+
* fhandler_disk_file.cc (fhandler_disk_file::link): Drop faking hardlink
creation on filesystems not supporting hardlinks.
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index 9bba99a65..7a39de627 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -211,8 +211,8 @@ public:
UNICODE_STRING win32;
DWORD drive_length;
static muto cwd_lock;
- char *get_posix ();
- void reset_posix () { if (posix) posix[0] = '\0'; }
+ const char *get_posix () const { return posix; };
+ void reset_posix (wchar_t *);
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/path.cc b/winsup/cygwin/path.cc
index db514d325..223cc2331 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -3306,8 +3306,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);
}
- if (posix)
- posix[0] = '\0';
+ posix = (char *) crealloc_abort (posix, strlen (posix_cwd) + 1);
+ stpcpy (posix, posix_cwd);
}
out:
@@ -3315,20 +3315,14 @@ out:
return res;
}
-/* Copy the value for either the posix or the win32 cwd into a buffer. */
-char *
-cwdstuff::get_posix ()
+/* Store incoming wchar_t path as current posix cwd. This is called from
+ setlocale so that the cwd is always stored in the right charset. */
+void
+cwdstuff::reset_posix (wchar_t *w_cwd)
{
- 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;
+ size_t len = sys_wcstombs (NULL, (size_t) -1, w_cwd);
+ posix = (char *) crealloc_abort (posix, len + 1);
+ sys_wcstombs (posix, len + 1, w_cwd);
}
char *
@@ -3356,13 +3350,6 @@ 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/syscalls.cc b/winsup/cygwin/syscalls.cc
index e86163886..a436afd52 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -4063,6 +4063,16 @@ unlinkat (int dirfd, const char *pathname, int flags)
static char *
internal_setlocale (char *ret)
{
+ tmp_pathbuf tp;
+
+ /* Each setlocale potentially changes the multibyte representation
+ of the CWD. Therefore we have to reevaluate the CWD's posix path and
+ store in the new charset. */
+ /* FIXME: Other buffered paths might be affected as well. */
+ wchar_t *w_cwd = tp.w_get ();
+ cwdstuff::cwd_lock.acquire ();
+ sys_mbstowcs (w_cwd, 32768, cygheap->cwd.get_posix ());
+
if (*__locale_charset () == 'A')
{
cygheap->locale.mbtowc = __utf8_mbtowc;
@@ -4097,11 +4107,10 @@ internal_setlocale (char *ret)
cygheap->locale.wctomb = __wctomb;
}
strcpy (cygheap->locale.charset, __locale_charset ());
- /* Each setlocale potentially changes the multibyte representation
- of the CWD. Therefore we have to reset the CWD's posix path and
- reevaluate the next time it's used. */
- /* FIXME: Other buffered paths might be affected as well. */
- cygheap->cwd.reset_posix ();
+
+ /* See above. */
+ cygheap->cwd.reset_posix (w_cwd);
+ cwdstuff::cwd_lock.release ();
return ret;
}