* 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:
		
							parent
							
								
									136033a852
								
							
						
					
					
						commit
						b6c6ea43f3
					
				| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue