* 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.
This commit is contained in:
		| @@ -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. | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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\ | ||||
|   | ||||
| @@ -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))) | ||||
|   | ||||
| @@ -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: | ||||
| @@ -3240,6 +3240,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) | ||||
| { | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user