* 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:
parent
63f33caadc
commit
2ffc166d07
@ -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>
|
2006-12-06 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* termios.cc: Change include order to accomodate change to sys/ioctl.h.
|
* termios.cc: Change include order to accomodate change to sys/ioctl.h.
|
||||||
|
@ -230,6 +230,7 @@ struct cwdstuff
|
|||||||
char *win32;
|
char *win32;
|
||||||
DWORD hash;
|
DWORD hash;
|
||||||
DWORD drive_length;
|
DWORD drive_length;
|
||||||
|
bool sync;
|
||||||
static muto cwd_lock;
|
static muto cwd_lock;
|
||||||
char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH);
|
char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH);
|
||||||
DWORD get_hash ();
|
DWORD get_hash ();
|
||||||
@ -244,6 +245,8 @@ struct cwdstuff
|
|||||||
void fixup_after_exec (char *, char *, DWORD);
|
void fixup_after_exec (char *, char *, DWORD);
|
||||||
bool get_initial ();
|
bool get_initial ();
|
||||||
int set (const char *, const char *, bool);
|
int set (const char *, const char *, bool);
|
||||||
|
bool keep_in_sync () const { return sync; }
|
||||||
|
void keep_in_sync (bool val);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
|
@ -346,6 +346,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||||||
try_to_debug ();
|
try_to_debug ();
|
||||||
break;
|
break;
|
||||||
case CW_SYNC_WINENV:
|
case CW_SYNC_WINENV:
|
||||||
|
cygheap->cwd.keep_in_sync (true);
|
||||||
sync_winenv ();
|
sync_winenv ();
|
||||||
return 0;
|
return 0;
|
||||||
case CW_CYGTLS_PADSIZE:
|
case CW_CYGTLS_PADSIZE:
|
||||||
|
@ -4150,6 +4150,8 @@ cwdstuff::get_hash ()
|
|||||||
return hashnow;
|
return hashnow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern char windows_system_directory[];
|
||||||
|
|
||||||
/* Initialize cygcwd 'muto' for serializing access to cwd info. */
|
/* Initialize cygcwd 'muto' for serializing access to cwd info. */
|
||||||
void
|
void
|
||||||
cwdstuff::init ()
|
cwdstuff::init ()
|
||||||
@ -4157,16 +4159,22 @@ cwdstuff::init ()
|
|||||||
extern int dynamically_loaded;
|
extern int dynamically_loaded;
|
||||||
cwd_lock.init ("cwd_lock");
|
cwd_lock.init ("cwd_lock");
|
||||||
get_initial ();
|
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. */
|
in cwdstuff::set below. */
|
||||||
extern char windows_system_directory[];
|
|
||||||
SetCurrentDirectory (windows_system_directory);
|
SetCurrentDirectory (windows_system_directory);
|
||||||
}
|
}
|
||||||
cwd_lock.release ();
|
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
|
/* Get initial cwd. Should only be called once in a
|
||||||
process tree. */
|
process tree. */
|
||||||
bool
|
bool
|
||||||
@ -4195,40 +4203,55 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
|
|||||||
cwd_lock.acquire ();
|
cwd_lock.acquire ();
|
||||||
if (doit)
|
if (doit)
|
||||||
{
|
{
|
||||||
/* Check if we *could* chdir, if we actually would.
|
if (keep_in_sync ())
|
||||||
|
|
||||||
Why don't we actually chdir? For two reasons:
|
|
||||||
- A process has always an open handle to the current working
|
|
||||||
directory which disallows manipulating this directory.
|
|
||||||
POSIX allows to remove a directory if the permissions are
|
|
||||||
ok. The fact that its the cwd of some process doesn't matter.
|
|
||||||
- SetCurrentDirectory fails for directories with strict
|
|
||||||
permissions even for processes with the SE_BACKUP_NAME
|
|
||||||
privilege enabled. The reason is apparently that
|
|
||||||
SetCurrentDirectory calls NtOpenFile without the
|
|
||||||
FILE_OPEN_FOR_BACKUP_INTENT flag set. */
|
|
||||||
DWORD attr = GetFileAttributes (win32_cwd);
|
|
||||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
|
||||||
{
|
{
|
||||||
set_errno (ENOENT);
|
/* If a Cygwin application called cygwin_internal(CW_SYNC_WINENV),
|
||||||
goto out;
|
then it's about to call native Windows functions. This also
|
||||||
}
|
sets the keep_in_sync flag so that we actually chdir into the
|
||||||
if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
|
native directory to avoid confusion. */
|
||||||
{
|
if (!SetCurrentDirectory (win32_cwd))
|
||||||
set_errno (ENOTDIR);
|
{
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (wincap.can_open_directories ())
|
|
||||||
{
|
|
||||||
HANDLE h = CreateFile (win32_cwd, GENERIC_READ, wincap.shared (),
|
|
||||||
NULL, OPEN_EXISTING,
|
|
||||||
FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
|
||||||
if (h == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
CloseHandle (h);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check if we *could* chdir, if we actually would.
|
||||||
|
|
||||||
|
Why don't we actually chdir? For two reasons:
|
||||||
|
- A process has always an open handle to the current working
|
||||||
|
directory which disallows manipulating this directory.
|
||||||
|
POSIX allows to remove a directory if the permissions are
|
||||||
|
ok. The fact that its the cwd of some process doesn't matter.
|
||||||
|
- SetCurrentDirectory fails for directories with strict
|
||||||
|
permissions even for processes with the SE_BACKUP_NAME
|
||||||
|
privilege enabled. The reason is apparently that
|
||||||
|
SetCurrentDirectory calls NtOpenFile without the
|
||||||
|
FILE_OPEN_FOR_BACKUP_INTENT flag set. */
|
||||||
|
DWORD attr = GetFileAttributes (win32_cwd);
|
||||||
|
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
set_errno (ENOENT);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
{
|
||||||
|
set_errno (ENOTDIR);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (wincap.can_open_directories ())
|
||||||
|
{
|
||||||
|
HANDLE h = CreateFile (win32_cwd, GENERIC_READ,
|
||||||
|
wincap.shared (), NULL, OPEN_EXISTING,
|
||||||
|
FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||||
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
CloseHandle (h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user