diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/fileio.c | 93 |
1 files changed, 61 insertions, 32 deletions
diff --git a/src/fileio.c b/src/fileio.c index f3f8f421618..eec3591ff6e 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -2236,13 +2236,10 @@ internal_delete_file (Lisp_Object filename) | |||
| 2236 | return NILP (tem); | 2236 | return NILP (tem); |
| 2237 | } | 2237 | } |
| 2238 | 2238 | ||
| 2239 | /* Filesystems are case-sensitive on all supported systems except | 2239 | /* Return true if FILENAME is on a case-insensitive file system. |
| 2240 | MS-Windows, MS-DOS, Cygwin, and Mac OS X. They are always | 2240 | Use a runtime test if available. Otherwise, assume the file system |
| 2241 | case-insensitive on the first two, but they may or may not be | 2241 | is case-insensitive on Microsoft-based platforms and case-sensitive |
| 2242 | case-insensitive on Cygwin and OS X. The following function | 2242 | elsewhere. |
| 2243 | attempts to provide a runtime test on those two systems. If the | ||
| 2244 | test is not conclusive, we assume case-insensitivity on Cygwin and | ||
| 2245 | case-sensitivity on Mac OS X. | ||
| 2246 | 2243 | ||
| 2247 | FIXME: Mounted filesystems on Posix hosts, like Samba shares or | 2244 | FIXME: Mounted filesystems on Posix hosts, like Samba shares or |
| 2248 | NFS-mounted Windows volumes, might be case-insensitive. Can we | 2245 | NFS-mounted Windows volumes, might be case-insensitive. Can we |
| @@ -2251,33 +2248,65 @@ internal_delete_file (Lisp_Object filename) | |||
| 2251 | static bool | 2248 | static bool |
| 2252 | file_name_case_insensitive_p (const char *filename) | 2249 | file_name_case_insensitive_p (const char *filename) |
| 2253 | { | 2250 | { |
| 2254 | #ifdef DOS_NT | 2251 | #ifdef _PC_CASE_INSENSITIVE |
| 2255 | return 1; | ||
| 2256 | #elif defined CYGWIN | ||
| 2257 | /* As of Cygwin-2.6.1, pathconf supports _PC_CASE_INSENSITIVE. */ | ||
| 2258 | # ifdef _PC_CASE_INSENSITIVE | ||
| 2259 | int res = pathconf (filename, _PC_CASE_INSENSITIVE); | 2252 | int res = pathconf (filename, _PC_CASE_INSENSITIVE); |
| 2260 | if (res < 0) | 2253 | if (0 < res) |
| 2261 | return 1; | 2254 | return true; |
| 2262 | return res > 0; | 2255 | if (res == 0 || errno != EINVAL) |
| 2263 | # else | 2256 | return false; |
| 2264 | return 1; | 2257 | #elif defined _PC_CASE_SENSITIVE |
| 2258 | int res = pathconf (filename, _PC_CASE_SENSITIVE); | ||
| 2259 | if (res == 0) | ||
| 2260 | return true; | ||
| 2261 | if (0 < res || errno != EINVAL) | ||
| 2262 | return false; | ||
| 2263 | #endif | ||
| 2264 | |||
| 2265 | #ifdef DARWIN_OS | ||
| 2266 | /* It is not clear whether this section is needed. For now, rely on | ||
| 2267 | pathconf and skip this section. If pathconf does not work, | ||
| 2268 | please recompile Emacs with -DDARWIN_OS_CASE_SENSITIVE_FIXME=1 or | ||
| 2269 | -DDARWIN_OS_CASE_SENSITIVE_FIXME=2, and file a bug report saying | ||
| 2270 | whether this fixed your problem. */ | ||
| 2271 | # ifndef DARWIN_OS_CASE_SENSITIVE_FIXME | ||
| 2272 | int DARWIN_OS_CASE_SENSITIVE_FIXME = 0; | ||
| 2265 | # endif | 2273 | # endif |
| 2266 | #elif defined DARWIN_OS | 2274 | |
| 2267 | /* The following is based on | 2275 | if (DARWIN_OS_CASE_SENSITIVE_FIXME == 1) |
| 2268 | http://lists.apple.com/archives/darwin-dev/2007/Apr/msg00010.html. */ | 2276 | { |
| 2269 | struct attrlist alist; | 2277 | /* This is based on developer.apple.com's getattrlist man page. */ |
| 2270 | unsigned char buffer[sizeof (vol_capabilities_attr_t) + sizeof (size_t)]; | 2278 | struct attrlist alist = {.volattr = ATTR_VOL_CAPABILITIES}; |
| 2271 | 2279 | struct vol_capabilities_attr_t vcaps; | |
| 2272 | memset (&alist, 0, sizeof (alist)); | 2280 | if (getattrlist (filename, &alist, &vcaps, sizeof vcaps, 0) == 0) |
| 2273 | alist.volattr = ATTR_VOL_CAPABILITIES; | 2281 | { |
| 2274 | if (getattrlist (filename, &alist, buffer, sizeof (buffer), 0) | 2282 | if (vcaps.valid[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_CASE_SENSITIVE) |
| 2275 | || !(alist.volattr & ATTR_VOL_CAPABILITIES)) | 2283 | return ! (vcaps.capabilities[VOL_CAPABILITIES_FORMAT] |
| 2276 | return 0; | 2284 | & VOL_CAP_FMT_CASE_SENSITIVE); |
| 2277 | vol_capabilities_attr_t *vcaps = buffer; | 2285 | } |
| 2278 | return !(vcaps->capabilities[0] & VOL_CAP_FMT_CASE_SENSITIVE); | 2286 | else if (errno != EINVAL) |
| 2287 | return false; | ||
| 2288 | } | ||
| 2289 | else if (DARWIN_OS_CASE_SENSITIVE_FIXME == 2) | ||
| 2290 | { | ||
| 2291 | /* The following is based on | ||
| 2292 | http://lists.apple.com/archives/darwin-dev/2007/Apr/msg00010.html. */ | ||
| 2293 | struct attrlist alist; | ||
| 2294 | unsigned char buffer[sizeof (vol_capabilities_attr_t) + sizeof (size_t)]; | ||
| 2295 | |||
| 2296 | memset (&alist, 0, sizeof (alist)); | ||
| 2297 | alist.volattr = ATTR_VOL_CAPABILITIES; | ||
| 2298 | if (getattrlist (filename, &alist, buffer, sizeof (buffer), 0) | ||
| 2299 | || !(alist.volattr & ATTR_VOL_CAPABILITIES)) | ||
| 2300 | return 0; | ||
| 2301 | vol_capabilities_attr_t *vcaps = buffer; | ||
| 2302 | return !(vcaps->capabilities[0] & VOL_CAP_FMT_CASE_SENSITIVE); | ||
| 2303 | } | ||
| 2304 | #endif | ||
| 2305 | |||
| 2306 | #if defined CYGWIN || defined DOS_NT | ||
| 2307 | return true; | ||
| 2279 | #else | 2308 | #else |
| 2280 | return 0; | 2309 | return false; |
| 2281 | #endif | 2310 | #endif |
| 2282 | } | 2311 | } |
| 2283 | 2312 | ||
| @@ -2349,7 +2378,7 @@ This is what happens in interactive use with M-x. */) | |||
| 2349 | /* If the filesystem is case-insensitive and the file names are | 2378 | /* If the filesystem is case-insensitive and the file names are |
| 2350 | identical but for the case, don't ask for confirmation: they | 2379 | identical but for the case, don't ask for confirmation: they |
| 2351 | simply want to change the letter-case of the file name. */ | 2380 | simply want to change the letter-case of the file name. */ |
| 2352 | if ((!(file_name_case_insensitive_p (SSDATA (encoded_file))) | 2381 | if ((! file_name_case_insensitive_p (SSDATA (encoded_file)) |
| 2353 | || NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))) | 2382 | || NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))) |
| 2354 | && ((NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists)))) | 2383 | && ((NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists)))) |
| 2355 | barf_or_query_if_file_exists (newname, false, "rename to it", | 2384 | barf_or_query_if_file_exists (newname, false, "rename to it", |