Jonathan Lennox <lennox <at> cs.columbia.edu> writes: > On Cygwin using non-managed mounts (and presumably other operating systems > when using a case-insensitive file system), it's not possible to use > Coreutils mv to change the case of a filename; mv reports that they are the > same file.
There is another case-insensitive file system issue that I hope we can clean up in the process, which affects both mv and cp: $ mkdir a b c $ touch a/a b/a $ cp -vR a/* b/* c `a/a' -> `c/a' cp: will not overwrite just-created `c/a' with `b/a' But $ mkdir a b c $ echo 1 > a/A $ echo 2 > b/a $ cp -vR a/* b/* c `a/A' -> `c/A' `b/a' -> `c/a' $ ls c A $ cat c/a 2 Oops - we got the spelling of a/A but the contents of b/a (the result is corrupted), because we did not detect the clash in the case-insensitive filenames. And had we used 'mv -v' instead of 'cp -vR', the result is the silent loss of data, which is contrary to the goal of mv. Maybe a first step is teaching same_name in gnulib's same.c about case- insensitive directories. But it would sure be a lot easier if there were a reliable way to tell if a directory entry of a different case in a case- insensitive directory already exists (or, put another way, it would be nice if something like realpath could be used to fess up to the canonical case spelling of a directory entry but without dereferencing the final symlink; canonicalize_filename_mode(CAN_ALL_BUT_LAST) doesn't cut it as currently implemented). Even something like pathconf(dir, _PC_CASE_INSENSITIVE) would be useful, but again, that is not standardized. Lacking an efficient standardized API, checks for case-insensitivity are only needed when stricmp() succeeds when strcmp() fails (actually, I'm not sure whether choice of locale can affect case-insensitive equality of filenames?). So a first-order approximation is doing a stricmp()/strcmp() filter, and when that shows a possible clash, use stat() on both spellings and declare that the directory is case-insensitive if the inodes match and the link count is 1. But that still doesn't solve the ambiguity when foo and Foo have the same inode, but link count > 1, because we still can't tell if foo and Foo are case- sensitive hard links to each other or if foo is a hardlink to bar and Foo is a case-insensitive reference to foo. At this point, about the only way I can see to portably resolve that ambiguity is with a readdir() search. You can see where this is headed - it is adding a LOT of overhead into checking for the corner-case of case-insensitivity, where such overhead is unnecessary if you comply with POSIX and have no case-insensitive file systems in the first place. Maybe now is the time to start lobbying for cygwin, Mac, and Linux to agree on a way to efficiently identify case-insensitive directories? On the other hand, since gnulib doesn't mind platform-specific code inside generic APIs, I could easily prepare a gnulib patch for same_name() that answers the question correctly for cygwin (it won't help for Mac or Linux, or any other system that has a way to mount FAT, HFS, or NTFS systems case- insensitively, but support for additional systems can be added to gnulib as solutions are encountered). Christian Franke proposed an idea for such a patch here: http://cygwin.com/ml/cygwin-developers/2007-08/msg00030.html -- Eric Blake _______________________________________________ Bug-coreutils mailing list [email protected] http://lists.gnu.org/mailman/listinfo/bug-coreutils
