Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2006-12-07 13:04:52 +0300
committerCorinna Vinschen <corinna@vinschen.de>2006-12-07 13:04:52 +0300
commit2ffc166d0765bec680139e82dd50723ea0e53364 (patch)
tree0ecac92f6efce9cde38d03b8b919d351dec2feb1 /winsup
parent63f33caadc1f91f229059756c4117cdb99605706 (diff)
* 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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/cygheap.h3
-rw-r--r--winsup/cygwin/external.cc1
-rw-r--r--winsup/cygwin/path.cc85
4 files changed, 69 insertions, 31 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 7224b634f..c69b81340 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index 85da8f6ed..0c54bad1a 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -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
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index 757cd276c..9d092759a 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -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:
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index b415a30dc..49d3aecc3 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -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
@@ -4195,40 +4203,55 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
cwd_lock.acquire ();
if (doit)
{
- /* 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)
+ if (keep_in_sync ())
{
- set_errno (ENOENT);
- goto out;
- }
- if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
- {
- set_errno (ENOTDIR);
- goto out;
+ /* 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;
+ }
}
- if (wincap.can_open_directories ())
+ else
{
- HANDLE h = CreateFile (win32_cwd, GENERIC_READ, wincap.shared (),
- NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (h == INVALID_HANDLE_VALUE)
+ /* 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)
{
- __seterrno ();
+ set_errno (ENOENT);
+ goto out;
+ }
+ if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ set_errno (ENOTDIR);
goto out;
}
- CloseHandle (h);
+ 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);
+ }
}
}
}