From 93cd4ee1fc261bca5d9d54f6e1366e74668ccc29 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 14 Nov 2016 17:26:12 -0500 Subject: [PATCH] Simplify case-insensitivity checks on Mac OS X * src/fileio.c (file_name_case_insensitive_p): Try skipping the Darwin code and instead using pathconf with _PC_CASE_SENSITIVE. Leave in two alternatives conditionally compiled based on DARWIN_OS_CASE_SENSITIVE_FIXME in case pathconf doesn't work. --- src/fileio.c | 81 ++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/src/fileio.c b/src/fileio.c index f3f8f42..70799eb 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2251,33 +2251,66 @@ internal_delete_file (Lisp_Object filename) static bool file_name_case_insensitive_p (const char *filename) { -#ifdef DOS_NT - return 1; -#elif defined CYGWIN -/* As of Cygwin-2.6.1, pathconf supports _PC_CASE_INSENSITIVE. */ -# ifdef _PC_CASE_INSENSITIVE + /* Use pathconf with _PC_CASE_INSENSITIVE or _PC_CASE_SENSITIVE if + those flags are available. As of this writing (2016-11-14), + Cygwin is the only platform known to support the former (starting + with Cygwin-2.6.1), and Mac OS X is the only platform known to + support the latter. + + There have been reports that pathconf with _PC_CASE_SENSITIVE + does not work reliably on Mac OS X. If you have a problem, + please recompile Emacs with -DDARWIN_OS_CASE_SENSITIVE_FIXME=1 or + -DDARWIN_OS_CASE_SENSITIVE_FIXME=2, and file a bug report saying + whether this fixed your problem. */ + +#ifdef _PC_CASE_INSENSITIVE int res = pathconf (filename, _PC_CASE_INSENSITIVE); - if (res < 0) - return 1; - return res > 0; -# else - return 1; + if (res >= 0) + return res > 0; +#elif defined _PC_CASE_SENSITIVE && !defined DARWIN_OS_CASE_SENSITIVE_FIXME + int res = pathconf (filename, _PC_CASE_SENSITIVE); + if (res >= 0) + return res == 0; +#endif + +#ifdef DARWIN_OS +# ifndef DARWIN_OS_CASE_SENSITIVE_FIXME + int DARWIN_OS_CASE_SENSITIVE_FIXME = 0; # endif -#elif defined DARWIN_OS - /* The following is based on - http://lists.apple.com/archives/darwin-dev/2007/Apr/msg00010.html. */ - struct attrlist alist; - unsigned char buffer[sizeof (vol_capabilities_attr_t) + sizeof (size_t)]; - - memset (&alist, 0, sizeof (alist)); - alist.volattr = ATTR_VOL_CAPABILITIES; - if (getattrlist (filename, &alist, buffer, sizeof (buffer), 0) - || !(alist.volattr & ATTR_VOL_CAPABILITIES)) - return 0; - vol_capabilities_attr_t *vcaps = buffer; - return !(vcaps->capabilities[0] & VOL_CAP_FMT_CASE_SENSITIVE); + + if (DARWIN_OS_CASE_SENSITIVE_FIXME == 1) + { + /* This is based on developer.apple.com's getattrlist man page. */ + struct attrlist alist = {.volattr = ATTR_VOL_CAPABILITIES}; + struct vol_capabilities_attr_t vcaps; + if (getattrlist (filename, &alist, &vcaps, sizeof vcaps, 0) == 0) + { + if (vcaps.valid[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_CASE_SENSITIVE) + return ! (vcaps.capabilities[VOL_CAPABILITIES_FORMAT] + & VOL_CAP_FMT_CASE_SENSITIVE); + } + } + else if (DARWIN_OS_CASE_SENSITIVE_FIXME == 2) + { + /* The following is based on + http://lists.apple.com/archives/darwin-dev/2007/Apr/msg00010.html. */ + struct attrlist alist; + unsigned char buffer[sizeof (vol_capabilities_attr_t) sizeof (size_t)]; + + memset (&alist, 0, sizeof (alist)); + alist.volattr = ATTR_VOL_CAPABILITIES; + if (getattrlist (filename, &alist, buffer, sizeof (buffer), 0) + || !(alist.volattr & ATTR_VOL_CAPABILITIES)) + return 0; + vol_capabilities_attr_t *vcaps = buffer; + return !(vcaps->capabilities[0] & VOL_CAP_FMT_CASE_SENSITIVE); + } +#endif /* DARWIN_OS */ + +#if defined CYGWIN || defined DOS_NT + return true; #else - return 0; + return false; #endif } -- 2.8.3