* external.cc (sync_wincwd): Remove.

(cygwin_internal): Drop CW_SYNC_WINCWD case.
	* globals.cc (ro_u_pipedir): New R/O unicode string.
	* ntdll.h (RtlSetCurrentDirectory_U): Declare.
	* path.cc (cwdstuff::set): Improve comments.  Drop setting Win32 CWD to
	\\?\PIPE\ on init.  Keep Win32 CWD in sync, if possible.  Set to
	\\?\PIPE\ otherwise.
	* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Revert to 230.
	* include/sys/cygwin.h (cygwin_getinfo_types): Remove CW_SYNC_WINCWD.
This commit is contained in:
Corinna Vinschen 2010-08-27 17:58:45 +00:00
parent 95c929196b
commit 1121c57f54
7 changed files with 52 additions and 53 deletions

View File

@ -1,3 +1,15 @@
2010-08-27 Corinna Vinschen <corinna@vinschen.de>
* external.cc (sync_wincwd): Remove.
(cygwin_internal): Drop CW_SYNC_WINCWD case.
* globals.cc (ro_u_pipedir): New R/O unicode string.
* ntdll.h (RtlSetCurrentDirectory_U): Declare.
* path.cc (cwdstuff::set): Improve comments. Drop setting Win32 CWD to
\\?\PIPE\ on init. Keep Win32 CWD in sync, if possible. Set to
\\?\PIPE\ otherwise.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Revert to 230.
* include/sys/cygwin.h (cygwin_getinfo_types): Remove CW_SYNC_WINCWD.
2010-08-27 Corinna Vinschen <corinna@vinschen.de>
* fhandler_proc.cc (format_proc_partitions): Improve comment.

View File

@ -162,29 +162,6 @@ sync_winenv ()
free (envblock);
}
/* Synchronize Win32 CWD with Cygwin CWD. Return -1 and set errno if
setting the Win32 CWD fails. */
static unsigned long
sync_wincwd ()
{
unsigned long ret = (unsigned long) -1;
/* Lock cwd. We're accessing it directly here. */
cygheap->cwd.cwd_lock.acquire ();
/* First check if the path can work at all. Fortunately we already have
an error code in the cwd, which was stored there for the sake of
spawn_guts. */
if (cygheap->cwd.get_error ())
set_errno (cygheap->cwd.get_error ());
/* Of course, SetCurrentDirectoryW still can fail, for instance, if the
CWD has been removed or renamed in the meantime. */
else if (!SetCurrentDirectoryW (cygheap->cwd.win32.Buffer))
__seterrno ();
else
ret = 0;
cygheap->cwd.cwd_lock.release ();
return ret;
}
/*
* Cygwin-specific wrapper for win32 ExitProcess and TerminateProcess.
* It ensures that the correct exit code, derived from the specified
@ -537,9 +514,6 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = (uintptr_t) strerror (err);
}
break;
case CW_SYNC_WINCWD:
res = sync_wincwd ();
break;
default:
set_errno (ENOSYS);

View File

@ -109,6 +109,7 @@ UNICODE_STRING _RDATA ro_u_udf = _ROU (L"UDF");
UNICODE_STRING _RDATA ro_u_unixfs = _ROU (L"UNIXFS");
UNICODE_STRING _RDATA ro_u_nwfs = _ROU (L"NWFS");
UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{");
UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\");
#undef _ROU
/* Cygwin properties are meant to be readonly data placed in the DLL, but

View File

@ -390,13 +390,12 @@ details. */
228: CW_STRERROR added.
229: Add mkostemp, mkostemps.
230: Add CLOCK_MONOTONIC.
231: CW_SYNC_WINCWD.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 231
#define CYGWIN_VERSION_API_MINOR 230
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible

View File

@ -149,8 +149,7 @@ typedef enum
CW_INT_SETLOCALE,
CW_CVT_MNT_OPTS,
CW_LST_MNT_OPTS,
CW_STRERROR,
CW_SYNC_WINCWD
CW_STRERROR
} cygwin_getinfo_types;
/* Token type for CW_SET_EXTERNAL_TOKEN */

View File

@ -1005,6 +1005,7 @@ extern "C"
BOOLEAN);
VOID NTAPI RtlReleasePebLock ();
VOID NTAPI RtlSecondsSince1970ToTime (ULONG, PLARGE_INTEGER);
NTSTATUS NTAPI RtlSetCurrentDirectory_U (PUNICODE_STRING);
BOOLEAN NTAPI RtlSetCurrentTransaction (HANDLE);
NTSTATUS NTAPI RtlUnicodeStringToAnsiString (PANSI_STRING, PUNICODE_STRING,
BOOLEAN);

View File

@ -3286,36 +3286,48 @@ cwdstuff::init ()
int
cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
{
NTSTATUS status;
UNICODE_STRING upath;
bool virtual_path = false;
bool unc_path = false;
bool inaccessible_path = false;
/* Here are the problems with using SetCurrentDirectory:
/* Here are the problems with using SetCurrentDirectory. Just skip this
comment if you don't like whining.
- SetCurrentDirectory only supports paths of up to MAX_PATH - 1 chars,
including a trailing backslash. That's an absolute restriction, even
in the UNICODE API.
- 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
- 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.
- SetCurrentDirectory does not support case-sensitivity.
- Unlinking a cwd fails because SetCurrentDirectory seems to
open directories so that deleting the directory is disallowed.
- Unlinking a cwd fails because SetCurrentDirectory seems to open
directories so that deleting the directory is disallowed.
- SetCurrentDirectory can naturally not work on virtual Cygwin paths
like /proc or /cygdrive.
Therefore, we do without SetCurrentDirectory and handle the CWD all
by ourselves. To avoid surprising behaviour in the Win32 API which
would stem from the fact that the Win32 CWD is different from the
POSIX CWD, we move the Win32 CWD to an invalid directory in which
typical relative Win32 path handling fails. */
Unfortunately, even though we have access to the Win32 process parameter
block, we can't just replace the directory handle. Starting with Vista,
the handle is used elsewhere, and just replacing the handle in the process
parameter block shows quite surprising results.
FIXME: If we ever find a *safe* way to replace the directory handle in
the process parameter block, we're back in business.
Nevertheless, doing entirely without SetCurrentDirectory is not really
feasible, because it breaks too many mixed applications using the Win32
API.
Therefore we handle the CWD all by ourselves and just keep the Win32
CWD in sync. However, to avoid surprising behaviour in the Win32 API
when we are in a CWD which is inaccessible as Win32 CWD, we set the
Win32 CWD to a "weird" directory in which all relative filesystem-related
calls fail. */
cwd_lock.acquire ();
@ -3332,7 +3344,6 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
HANDLE h = NULL;
if (!virtual_path)
{
NTSTATUS status;
IO_STATUS_BLOCK io;
OBJECT_ATTRIBUTES attr;
@ -3351,7 +3362,9 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
nat_cwd->objcaseinsensitive () | OBJ_INHERIT,
NULL, NULL);
/* First try without FILE_OPEN_FOR_BACKUP_INTENT, to find out if the
directory is valid for Win32 apps. */
directory is valid for Win32 apps. And, no, we can't just call
SetCurrentDirectory here, since that would potentially break
case-sensitivity. */
status = NtOpenFile (&h, SYNCHRONIZE | FILE_TRAVERSE, &attr, &io,
FILE_SHARE_VALID_FLAGS,
FILE_DIRECTORY_FILE
@ -3397,15 +3410,6 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
unc_path = true;
posix_cwd = NULL;
/* When inited move the actual Win32 CWD out of the way, as explained
above. Surprisingly, the PIPE filesystem seems to be usable as CWD
on all Windows systems. */
if (!SetCurrentDirectoryW (L"\\\\?\\PIPE\\"))
system_printf (
"WARNING: Couldn't set Win32 CWD to //?/PIPE (error %E). This will\n"
"probably not affect normal POSIX path operations. However, please report\n"
"this problem to the mailing list mailto:cygwin@cygwin.com. Thank you.");
}
else
{
@ -3468,6 +3472,15 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
else
error = 0;
}
/* Keep the Win32 CWD in sync. Don't check for error, other than for
strace output. Try to keep overhead low. */
if (nat_cwd)
{
status = RtlSetCurrentDirectory_U (error ? &ro_u_pipedir : &win32);
if (!NT_SUCCESS (status))
debug_printf ("RtlSetCurrentDirectory_U(%S) failed, %p",
error ? &ro_u_pipedir : &win32, status);
}
/* Eventually, create POSIX path if it's not set on entry. */
tmp_pathbuf tp;