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
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-01-31 17:18:49 +0300
committerCorinna Vinschen <corinna@vinschen.de>2008-01-31 17:18:49 +0300
commit8e87af7ed082bf06a30e226e6bc779c932db625a (patch)
treeef0ab0bf6cc1e64bd319bb7d7d6e5ce0410a4251
parent3fbb5e3d800ab4fb8ec8330dc9be7d769859c95a (diff)
* cygheap.h (struct cwdstuff): Add dir member to store cwd handle.
(cwdstuff::get_handle): New method. * path.cc (cwdstuff::set): When doit is true, always try to get directory handle. Fail if duplicating handle fails. Store handle in dir. Fix potential SEGV when setting drive_length.
-rw-r--r--winsup/cygwin/ChangeLog8
-rw-r--r--winsup/cygwin/cygheap.h2
-rw-r--r--winsup/cygwin/path.cc62
3 files changed, 41 insertions, 31 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index f88b56212..20af6ca60 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,11 @@
+2008-01-31 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygheap.h (struct cwdstuff): Add dir member to store cwd handle.
+ (cwdstuff::get_handle): New method.
+ * path.cc (cwdstuff::set): When doit is true, always try to get
+ directory handle. Fail if duplicating handle fails. Store handle
+ in dir. Fix potential SEGV when setting drive_length.
+
2008-01-28 Corinna Vinschen <corinna@vinschen.de>
* path.cc: Fix Samba version in comment.
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index f51b9a1e9..7d232584a 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -223,9 +223,11 @@ struct cwdstuff
{
char *posix;
UNICODE_STRING win32;
+ HANDLE dir;
DWORD drive_length;
static muto cwd_lock;
char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH);
+ HANDLE get_handle () { return dir; }
DWORD get_drive (char * dst)
{
cwd_lock.acquire ();
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index a3b0f007e..8d7703e40 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -4431,7 +4431,7 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
- Unlinking a cwd fails because SetCurrentDirectory seems to
open directories so that deleting the directory is disallowed.
The below code opens with *all* sharing flags set. */
- HANDLE h;
+ HANDLE h, h_copy;
NTSTATUS status;
IO_STATUS_BLOCK io;
OBJECT_ATTRIBUTES attr;
@@ -4441,18 +4441,6 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
phdl = &get_user_proc_parms ()->CurrentDirectoryHandle;
if (!nat_cwd) /* On init, just reopen CWD with desired access flags. */
RtlInitUnicodeString (&upath, L"");
- else
- {
- /* TODO:
- Check the length of the new CWD. Windows can only handle
- CWDs of up to MAX_PATH length, including a trailing backslash.
- If the path is longer, it's not an error condition for Cygwin,
- so we don't fail. Windows on the other hand has a problem now.
- For now, we just don't store the path in the PEB and proceed as
- usual. */
- if (len > MAX_PATH - (nat_cwd->Buffer[len - 1] == L'\\' ? 1 : 2))
- goto skip_peb_storing;
- }
InitializeObjectAttributes (&attr, &upath,
OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
nat_cwd ? NULL : *phdl, NULL);
@@ -4468,8 +4456,36 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
res = -1;
goto out;
}
+ /* Workaround a problem in Vista which fails in subsequent calls to
+ CreateFile with ERROR_INVALID_HANDLE if the handle in
+ CurrentDirectoryHandle changes without calling SetCurrentDirectory,
+ and the filename given to CreateFile is a relative path. It looks
+ like Vista stores a copy of the CWD handle in some other undocumented
+ place. The NtClose/DuplicateHandle reuses the original handle for
+ the copy of the new handle and the next CreateFile works.
+ Note that this is not thread-safe (yet?) */
+ if (!DuplicateHandle (GetCurrentProcess (), h, GetCurrentProcess (),
+ &h_copy, 0, TRUE, DUPLICATE_SAME_ACCESS))
+ {
+ RtlReleasePebLock ();
+ __seterrno ();
+ NtClose (h);
+ res = -1;
+ goto out;
+ }
+ NtClose (*phdl);
+ dir = *phdl = h;
- if (nat_cwd) /* No need to set path on init. */
+ /* No need to set path on init. */
+ if (nat_cwd
+ /* TODO:
+ Check the length of the new CWD. Windows can only handle
+ CWDs of up to MAX_PATH length, including a trailing backslash.
+ If the path is longer, it's not an error condition for Cygwin,
+ so we don't fail. Windows on the other hand has a problem now.
+ For now, we just don't store the path in the PEB and proceed as
+ usual. */
+ && len <= MAX_PATH - (nat_cwd->Buffer[len - 1] == L'\\' ? 1 : 2))
{
/* Convert to a Win32 path. */
upath.Buffer += upath.Length / sizeof (WCHAR) - len;
@@ -4485,22 +4501,6 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
RtlCopyUnicodeString (&get_user_proc_parms ()->CurrentDirectoryName,
&upath);
}
- NtClose (*phdl);
- /* Workaround a problem in Vista which fails in subsequent calls to
- CreateFile with ERROR_INVALID_HANDLE if the handle in
- CurrentDirectoryHandle changes without calling SetCurrentDirectory,
- and the filename given to CreateFile is a relative path. It looks
- like Vista stores a copy of the CWD handle in some other undocumented
- place. The NtClose/DuplicateHandle reuses the original handle for
- the copy of the new handle and the next CreateFile works.
- Note that this is not thread-safe (yet?) */
- if (DuplicateHandle (GetCurrentProcess (), h, GetCurrentProcess (), phdl,
- 0, TRUE, DUPLICATE_SAME_ACCESS))
- NtClose (h);
- else
- *phdl = h;
-
-skip_peb_storing:
RtlReleasePebLock ();
}
@@ -4552,7 +4552,7 @@ skip_peb_storing:
else if (win32.Buffer[1] == L'\\')
{
PWCHAR ptr = wcschr (win32.Buffer + 2, L'\\');
- if (*ptr)
+ if (ptr)
ptr = wcschr (ptr + 1, L'\\');
if (ptr)
drive_length = ptr - win32.Buffer;