From 6c43f249acd6d19a09ae0537958c802f0ec13b24 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 27 Aug 2010 18:56:28 +0000 Subject: [PATCH] * new-features.sgml (ov-new1.7.7): Change to describe partial reversion to pre-1.7.6 behaviour. (ov-new1.7.6): Deprecate description of CWD handling. * pathnames.sgml (pathnames-win32-api): Rewrite to reflect new CWD behaviour. --- winsup/doc/ChangeLog | 8 +++ winsup/doc/new-features.sgml | 14 ++-- winsup/doc/pathnames.sgml | 130 ++++++++++++++--------------------- 3 files changed, 69 insertions(+), 83 deletions(-) diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog index 48baf45f5..a1982377a 100644 --- a/winsup/doc/ChangeLog +++ b/winsup/doc/ChangeLog @@ -1,3 +1,11 @@ +2010-08-27 Corinna Vinschen + + * new-features.sgml (ov-new1.7.7): Change to describe partial + reversion to pre-1.7.6 behaviour. + (ov-new1.7.6): Deprecate description of CWD handling. + * pathnames.sgml (pathnames-win32-api): Rewrite to reflect new CWD + behaviour. + 2010-08-19 Corinna Vinschen * new-features.sgml (ov-new1.7.7): New section. diff --git a/winsup/doc/new-features.sgml b/winsup/doc/new-features.sgml index 9c23000ef..bc6caaa80 100644 --- a/winsup/doc/new-features.sgml +++ b/winsup/doc/new-features.sgml @@ -5,8 +5,11 @@ -Add a new CW_SYNC_WINCWD command to the cygwin_internal -call, to allow to synchronize the Win32 CWD with the Cygwin CWD. +Partially revert the 1.7.6 change to set the Win32 current working directory +(CWD) always to an invalid directory, since it breaks backward compatibility +too much. The Cygwin CWD and the Win32 CWD are now kept in sync again, unless +the Cygwin CWD is not usable as Win32 CWD. See the reworked + for details. @@ -61,10 +64,9 @@ clock_gettime(3) and clock_getres(3) accept CLOCK_MONOTONIC. -Cygwin handles the current working directory entirely on its own. The Win32 -current working directory is set to an invalid path to be out of the way. -This affects calls to the Win32 file API (CreateFile, etc.). See - for details. +DEPRECATED with 1.7.7: Cygwin handles the current working directory entirely +on its own. The Win32 current working directory is set to an invalid path to +be out of the way. [...] diff --git a/winsup/doc/pathnames.sgml b/winsup/doc/pathnames.sgml index 492f9cd17..f784ee15f 100644 --- a/winsup/doc/pathnames.sgml +++ b/winsup/doc/pathnames.sgml @@ -373,88 +373,64 @@ relative pathnames, or if your application uses functions like CreateProcess or ShellExecute to start other applications. -When a Cygwin application is started, the Win32 idea of the current -working directory (CWD) is set to an invalid -directory. This works around the problem that the Win32 CWD is locked -in a way which restricts certain POSIX functionality. However, the side -effect is that a call to, for instance, CreateFile ("foo", -...); will fail, since the Win32 notion of the CWD is -not the same as the Cygwin notion of the CWD, and worse, it's a -directory entirely unsuitable for normal file operations. +When a Cygwin application is started, the Windows idea of the current +working directory (CWD) is not necessarily the same as the Cygwin CWD. +There are a couple of restrictions in the Win32 API, which disallow certain +directories as Win32 CWD: + + + + The Windows subsystem only supports CWD paths of up to 258 chars. + This restriction doesn't apply for Cygwin processes, at least not as + long as they use the POSIX API (chdir, getcwd). This means, if a Cygwin + process has a CWD using an absolute path longer than 258 characters, the + Cygwin CWD and the Windows CWD differ. + + + + The Win32 API call to set the current directory, + SetCurrentDirectory, fails for directories for which + the user has no permissions, even if the user is an administrator. This + restriction doesn't apply for Cygwin processes, if they are running under + an administrator account. + + + + SetCurrentDirectory does not support + case-sensitive filenames. + + + + + Last, but not least, SetCurrentDirectory can't + work on virtual Cygwin paths like /proc or /cygdrive. These paths only + exists in the Cygwin realm so they have no meaning to a native Win32 + process. + + + +As long as the Cygwin CWD is usable as Windows CWD, the Cygwin and +Windows CWDs are in sync within a process. However, if the Cygwin process +changes its working directory into one of the directories which are +unusable as Windows CWD, we're in trouble. If the process uses the +Win32 API to access a file using a relative pathname, the resulting +absolute path would not match the expectations of the process. In the +worst case, the wrong files are deleted. + +To workaround this problem, Cygwin sets the Windows CWD to a special +directory in this case. This special directory points to a virtual +filesystem within the native NT namespace (\??\PIPE\). +Since it's not a real filesystem, the deliberate effect is that a call to, +for instance, CreateFile ("foo", ...); will fail, +as long as the processes CWD doesn't work as Windows CWD. So, in general, don't use the Win32 file API in Cygwin applications. If you really need to access files using the Win32 API, or if you really have to use CreateProcess to start applications, rather than -the POSIX exec(3) familiy of functions, you have to -make sure that the Win32 CWD is set to some valid directory. To -accomplish that, you can choose from several methods. - - - - The easiest method is to call - - - #include <sys/cygwin.h> - - cygwin_internal (CW_SYNC_WINCWD); - - - prior to calling the Win32 functions which require a valid Win32 CWD. - This function synchronizes the Win32 CWD with the Cygwin CWD. - - Note that the cygwin_internal (CW_SYNC_WINCWD) - call may fail. In that case, it returns with a non-zero value and - errno is set appropriately: - - - - - ENOTDIR - The Cygwin CWD is a virtual path, like /proc, or //, which does not - exist as valid directory in the Win32 namespace. - - - EACCES - The Cygwin CWD is a directory with restrictive permissions, - which make it unusable as Win32 directory. - - - ENAMETOOLONG - The Cygwin CWD is too long to be used as Win32 CWD. - The Win32 CWD is restricted to 258 characters. - - - - You should make sure that you test the return value of - cygwin_internal (CW_SYNC_WINCWD), otherwise - your application will potentially not work correctly. If the call - failed, you can use the Win32 call SetCurrentDirectory - to move to some well-known directory. - - After you've synchronized the Win32 CWD with the Cygwin CWD, - be aware that the directory is locked, until the process exited, or - until the process set the Win32 CWD to some other directory. During that - period it will not be possible to rename or remove the directory from - other Cygwin applications. - - - If you know where to go to, you can also just call the Win32 function - SetCurrentDirectory immediately. - - - If you need a valid Win32 CWD only for a child application started - via CreateProcess and friends, you don't have to - set your own Win32 CWD. In that case, just utilize the lpCurrentDirectory - parameter. See the description of the CreateProcess - function in the MSDN manual pages. - - - Last, but not least, if you don't need any POSIX function from - Cygwin in your specific applciation, consider to compile your application - as native Win32 (mingw) executable, rather than as Cygwin executable. - - +the POSIX exec(3) family of functions, you have to +make sure that the Cygwin CWD is set to some directory which is valid as +Win32 CWD.