From: Miles Bader Date: Sun, 7 Jul 1996 01:59:24 +0000 (+0000) Subject: (normalize_filename): Always lower-case drive letters, even on systems X-Git-Tag: emacs-19.34~247 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=5162ffce812c6639db8c34e27be839b1d4bc73d2;p=emacs.git (normalize_filename): Always lower-case drive letters, even on systems that preserve case in filenames. (sys_rename): Do not delete newname if only changing case. On Windows 95, use our version of mktemp (not the MSVC version) and give the temp name a long extension to ensure the final rename works as expected. --- diff --git a/src/w32.c b/src/w32.c index 4c621fc8fa4..2f30e30b2ac 100644 --- a/src/w32.c +++ b/src/w32.c @@ -401,6 +401,17 @@ normalize_filename (fp, path_sep) char sep; char *elem; + /* Always lower-case drive letters a-z, even if the filesystem + preserves case in filenames. + This is so filenames can be compared by string comparison + functions that are case-sensitive. Even case-preserving filesystems + do not distinguish case in drive letters. */ + if (fp[1] == ':' && *fp >= 'A' && *fp <= 'Z') + { + *fp += 'a' - 'A'; + fp += 2; + } + if (NILP (Vwin32_downcase_file_names)) { while (*fp) @@ -1050,11 +1061,20 @@ int sys_rename (const char * oldname, const char * newname) { char temp[MAX_PATH]; + DWORD attr; /* MoveFile on Win95 doesn't correctly change the short file name - alias when oldname has a three char extension and newname has the - same first three chars in its extension. To avoid problems, on - Win95 we rename to a temporary name first. */ + alias in a number of circumstances (it is not easy to predict when + just by looking at oldname and newname, unfortunately). In these + cases, renaming through a temporary name avoids the problem. + + A second problem on Win95 is that renaming through a temp name when + newname is uppercase fails (the final long name ends up in + lowercase, although the short alias might be uppercase) UNLESS the + long temp name is not 8.3. + + So, on Win95 we always rename through a temp name, and we make sure + the temp name has a long extension to ensure correct renaming. */ strcpy (temp, map_win32_filename (oldname, NULL)); @@ -1062,21 +1082,27 @@ sys_rename (const char * oldname, const char * newname) { char * p; - unixtodos_filename (temp); if (p = strrchr (temp, '\\')) p++; else p = temp; strcpy (p, "__XXXXXX"); - _mktemp (temp); + sys_mktemp (temp); + /* Force temp name to require a manufactured 8.3 alias - this + seems to make the second rename work properly. */ + strcat (temp, ".long"); if (rename (map_win32_filename (oldname, NULL), temp) < 0) return -1; } /* Emulate Unix behaviour - newname is deleted if it already exists - (at least if it is a file; don't do this for directories). */ + (at least if it is a file; don't do this for directories). + However, don't do this if we are just changing the case of the file + name - we will end up deleting the file we are trying to rename! */ newname = map_win32_filename (newname, NULL); - if (GetFileAttributes (newname) != -1) + if (stricmp (newname, temp) != 0 + && (attr = GetFileAttributes (newname)) != -1 + && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) { _chmod (newname, 0666); _unlink (newname);