* cygheap.h (struct cwdstuff): Add "sync" member and accompanying

"keep_in_sync" methods.
	* external.cc (cygwin_internal): Call above keep_in_sync method when
	CW_SYNC_WINENV is requested.
	* path.cc (cwdstuff::init): Don't change to windows_system_directory
	if keep_in_sync is requested.
	(cwdstuff::keep_in_sync): New method.
	(cwdstuff::set): Take sync flag into account.
This commit is contained in:
Corinna Vinschen 2006-12-07 10:04:52 +00:00
parent 63f33caadc
commit 2ffc166d07
4 changed files with 71 additions and 33 deletions

View File

@ -1,3 +1,14 @@
2006-12-07 Corinna Vinschen <corinna@vinschen.de>
* cygheap.h (struct cwdstuff): Add "sync" member and accompanying
"keep_in_sync" methods.
* external.cc (cygwin_internal): Call above keep_in_sync method when
CW_SYNC_WINENV is requested.
* path.cc (cwdstuff::init): Don't change to windows_system_directory
if keep_in_sync is requested.
(cwdstuff::keep_in_sync): New method.
(cwdstuff::set): Take sync flag into account.
2006-12-06 Corinna Vinschen <corinna@vinschen.de>
* termios.cc: Change include order to accomodate change to sys/ioctl.h.

View File

@ -230,6 +230,7 @@ struct cwdstuff
char *win32;
DWORD hash;
DWORD drive_length;
bool sync;
static muto cwd_lock;
char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH);
DWORD get_hash ();
@ -244,6 +245,8 @@ struct cwdstuff
void fixup_after_exec (char *, char *, DWORD);
bool get_initial ();
int set (const char *, const char *, bool);
bool keep_in_sync () const { return sync; }
void keep_in_sync (bool val);
};
#ifdef DEBUGGING

View File

@ -346,6 +346,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
try_to_debug ();
break;
case CW_SYNC_WINENV:
cygheap->cwd.keep_in_sync (true);
sync_winenv ();
return 0;
case CW_CYGTLS_PADSIZE:

View File

@ -4150,6 +4150,8 @@ cwdstuff::get_hash ()
return hashnow;
}
extern char windows_system_directory[];
/* Initialize cygcwd 'muto' for serializing access to cwd info. */
void
cwdstuff::init ()
@ -4157,16 +4159,22 @@ cwdstuff::init ()
extern int dynamically_loaded;
cwd_lock.init ("cwd_lock");
get_initial ();
if (!dynamically_loaded)
if (!dynamically_loaded && !keep_in_sync ())
{
/* Actually chdir into the syste dir to avoid cwd problems. See comment
/* Actually chdir into the system dir to avoid cwd problems. See comment
in cwdstuff::set below. */
extern char windows_system_directory[];
SetCurrentDirectory (windows_system_directory);
}
cwd_lock.release ();
}
void
cwdstuff::keep_in_sync (bool val)
{
sync = val;
SetCurrentDirectory (val ? win32 : windows_system_directory);
}
/* Get initial cwd. Should only be called once in a
process tree. */
bool
@ -4194,6 +4202,20 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
{
cwd_lock.acquire ();
if (doit)
{
if (keep_in_sync ())
{
/* If a Cygwin application called cygwin_internal(CW_SYNC_WINENV),
then it's about to call native Windows functions. This also
sets the keep_in_sync flag so that we actually chdir into the
native directory to avoid confusion. */
if (!SetCurrentDirectory (win32_cwd))
{
__seterrno ();
goto out;
}
}
else
{
/* Check if we *could* chdir, if we actually would.
@ -4220,8 +4242,8 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
}
if (wincap.can_open_directories ())
{
HANDLE h = CreateFile (win32_cwd, GENERIC_READ, wincap.shared (),
NULL, OPEN_EXISTING,
HANDLE h = CreateFile (win32_cwd, GENERIC_READ,
wincap.shared (), NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
{
@ -4232,6 +4254,7 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
}
}
}
}
/* If there is no win32 path or it has the form c:xxx, get the value */
if (!win32_cwd || (isdrive (win32_cwd) && win32_cwd[2] != '\\'))
{