diff options
| author | Miles Bader | 1996-07-07 01:59:24 +0000 |
|---|---|---|
| committer | Miles Bader | 1996-07-07 01:59:24 +0000 |
| commit | 5162ffce812c6639db8c34e27be839b1d4bc73d2 (patch) | |
| tree | 9260d77f36e0bd75dcd2d7a2a8243c7270bacba9 /src | |
| parent | ac4c237c27bab77712ed430cd0cbdf33eeb2ad07 (diff) | |
| download | emacs-5162ffce812c6639db8c34e27be839b1d4bc73d2.tar.gz emacs-5162ffce812c6639db8c34e27be839b1d4bc73d2.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32.c | 40 |
1 files changed, 33 insertions, 7 deletions
| @@ -401,6 +401,17 @@ normalize_filename (fp, path_sep) | |||
| 401 | char sep; | 401 | char sep; |
| 402 | char *elem; | 402 | char *elem; |
| 403 | 403 | ||
| 404 | /* Always lower-case drive letters a-z, even if the filesystem | ||
| 405 | preserves case in filenames. | ||
| 406 | This is so filenames can be compared by string comparison | ||
| 407 | functions that are case-sensitive. Even case-preserving filesystems | ||
| 408 | do not distinguish case in drive letters. */ | ||
| 409 | if (fp[1] == ':' && *fp >= 'A' && *fp <= 'Z') | ||
| 410 | { | ||
| 411 | *fp += 'a' - 'A'; | ||
| 412 | fp += 2; | ||
| 413 | } | ||
| 414 | |||
| 404 | if (NILP (Vwin32_downcase_file_names)) | 415 | if (NILP (Vwin32_downcase_file_names)) |
| 405 | { | 416 | { |
| 406 | while (*fp) | 417 | while (*fp) |
| @@ -1050,11 +1061,20 @@ int | |||
| 1050 | sys_rename (const char * oldname, const char * newname) | 1061 | sys_rename (const char * oldname, const char * newname) |
| 1051 | { | 1062 | { |
| 1052 | char temp[MAX_PATH]; | 1063 | char temp[MAX_PATH]; |
| 1064 | DWORD attr; | ||
| 1053 | 1065 | ||
| 1054 | /* MoveFile on Win95 doesn't correctly change the short file name | 1066 | /* MoveFile on Win95 doesn't correctly change the short file name |
| 1055 | alias when oldname has a three char extension and newname has the | 1067 | alias in a number of circumstances (it is not easy to predict when |
| 1056 | same first three chars in its extension. To avoid problems, on | 1068 | just by looking at oldname and newname, unfortunately). In these |
| 1057 | Win95 we rename to a temporary name first. */ | 1069 | cases, renaming through a temporary name avoids the problem. |
| 1070 | |||
| 1071 | A second problem on Win95 is that renaming through a temp name when | ||
| 1072 | newname is uppercase fails (the final long name ends up in | ||
| 1073 | lowercase, although the short alias might be uppercase) UNLESS the | ||
| 1074 | long temp name is not 8.3. | ||
| 1075 | |||
| 1076 | So, on Win95 we always rename through a temp name, and we make sure | ||
| 1077 | the temp name has a long extension to ensure correct renaming. */ | ||
| 1058 | 1078 | ||
| 1059 | strcpy (temp, map_win32_filename (oldname, NULL)); | 1079 | strcpy (temp, map_win32_filename (oldname, NULL)); |
| 1060 | 1080 | ||
| @@ -1062,21 +1082,27 @@ sys_rename (const char * oldname, const char * newname) | |||
| 1062 | { | 1082 | { |
| 1063 | char * p; | 1083 | char * p; |
| 1064 | 1084 | ||
| 1065 | unixtodos_filename (temp); | ||
| 1066 | if (p = strrchr (temp, '\\')) | 1085 | if (p = strrchr (temp, '\\')) |
| 1067 | p++; | 1086 | p++; |
| 1068 | else | 1087 | else |
| 1069 | p = temp; | 1088 | p = temp; |
| 1070 | strcpy (p, "__XXXXXX"); | 1089 | strcpy (p, "__XXXXXX"); |
| 1071 | _mktemp (temp); | 1090 | sys_mktemp (temp); |
| 1091 | /* Force temp name to require a manufactured 8.3 alias - this | ||
| 1092 | seems to make the second rename work properly. */ | ||
| 1093 | strcat (temp, ".long"); | ||
| 1072 | if (rename (map_win32_filename (oldname, NULL), temp) < 0) | 1094 | if (rename (map_win32_filename (oldname, NULL), temp) < 0) |
| 1073 | return -1; | 1095 | return -1; |
| 1074 | } | 1096 | } |
| 1075 | 1097 | ||
| 1076 | /* Emulate Unix behaviour - newname is deleted if it already exists | 1098 | /* Emulate Unix behaviour - newname is deleted if it already exists |
| 1077 | (at least if it is a file; don't do this for directories). */ | 1099 | (at least if it is a file; don't do this for directories). |
| 1100 | However, don't do this if we are just changing the case of the file | ||
| 1101 | name - we will end up deleting the file we are trying to rename! */ | ||
| 1078 | newname = map_win32_filename (newname, NULL); | 1102 | newname = map_win32_filename (newname, NULL); |
| 1079 | if (GetFileAttributes (newname) != -1) | 1103 | if (stricmp (newname, temp) != 0 |
| 1104 | && (attr = GetFileAttributes (newname)) != -1 | ||
| 1105 | && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) | ||
| 1080 | { | 1106 | { |
| 1081 | _chmod (newname, 0666); | 1107 | _chmod (newname, 0666); |
| 1082 | _unlink (newname); | 1108 | _unlink (newname); |