From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Ken Brown Newsgroups: gmane.emacs.bugs Subject: bug#24441: 24.5; rename directory in dired to change case Date: Thu, 10 Nov 2016 17:25:06 -0500 Message-ID: <8da158f4-21bb-8fb8-a56d-21d4cd967109@cornell.edu> References: < < <<3c49fbe5-9ae0-4ae2-8fa0-3c44fa85c981@default> <<83d1k56wwt.fsf@gnu.org> <7a1c7e15-4d84-400d-9735-a72a31408d6b@default> <834m5h6vg3.fsf@gnu.org> <5965f396-a65a-3d70-e67e-c3d680fe9e65@cornell.edu> <83zin95ddg.fsf@gnu.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------087F2E76C6F6CE762B53446A" X-Trace: blaine.gmane.org 1478816808 3830 195.159.176.226 (10 Nov 2016 22:26:48 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 10 Nov 2016 22:26:48 +0000 (UTC) User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 Cc: 24441@debbugs.gnu.org, schwab@suse.de, brady@bradyt.com To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Nov 10 23:26:43 2016 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1c4xnN-0004ts-Si for geb-bug-gnu-emacs@m.gmane.org; Thu, 10 Nov 2016 23:26:10 +0100 Original-Received: from localhost ([::1]:49627 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c4xnR-00067o-0N for geb-bug-gnu-emacs@m.gmane.org; Thu, 10 Nov 2016 17:26:13 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:34116) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c4xnJ-00067Y-VM for bug-gnu-emacs@gnu.org; Thu, 10 Nov 2016 17:26:07 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c4xnG-0007sk-5y for bug-gnu-emacs@gnu.org; Thu, 10 Nov 2016 17:26:05 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:37390) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1c4xnG-0007sg-28 for bug-gnu-emacs@gnu.org; Thu, 10 Nov 2016 17:26:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1c4xnF-0002Fs-T6 for bug-gnu-emacs@gnu.org; Thu, 10 Nov 2016 17:26:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Ken Brown Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 10 Nov 2016 22:26:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 24441 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 24441-submit@debbugs.gnu.org id=B24441.14788167258626 (code B ref 24441); Thu, 10 Nov 2016 22:26:01 +0000 Original-Received: (at 24441) by debbugs.gnu.org; 10 Nov 2016 22:25:25 +0000 Original-Received: from localhost ([127.0.0.1]:52789 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1c4xma-0002F0-PS for submit@debbugs.gnu.org; Thu, 10 Nov 2016 17:25:25 -0500 Original-Received: from limerock04.mail.cornell.edu ([128.84.13.244]:41597) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1c4xmZ-0002Eo-EX for 24441@debbugs.gnu.org; Thu, 10 Nov 2016 17:25:20 -0500 X-CornellRouted: This message has been Routed already. Original-Received: from authusersmtp.mail.cornell.edu (granite3.serverfarm.cornell.edu [10.16.197.8]) by limerock04.mail.cornell.edu (8.14.4/8.14.4_cu) with ESMTP id uAAMPBY8024635; Thu, 10 Nov 2016 17:25:12 -0500 Original-Received: from [10.128.155.185] (dhcp-gs-7097.eduroam.cornell.edu [10.128.155.185]) (authenticated bits=0) by authusersmtp.mail.cornell.edu (8.14.4/8.12.10) with ESMTP id uAAMP89M023058 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT); Thu, 10 Nov 2016 17:25:09 -0500 In-Reply-To: <83zin95ddg.fsf@gnu.org> X-PMX-Cornell-Gauge: Gauge=XX X-PMX-CORNELL-AUTH-RESULTS: dkim-out=none; X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:125594 Archived-At: This is a multi-part message in MIME format. --------------087F2E76C6F6CE762B53446A Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit On 9/15/2016 12:36 PM, Eli Zaretskii wrote: >> Cc: 24441@debbugs.gnu.org, schwab@suse.de, brady@bradyt.com >> From: Ken Brown >> Date: Thu, 15 Sep 2016 12:03:08 -0400 >> >>> See the bug I pointed to, where John explained that OS X filesystems >>> can be either case-sensitive or case-insensitive. >> >> FWIW, this is also true on Cygwin: >> >> >> https://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-casesensitive > > I was under the impression that most or all Cygwin users do use > case-sensitive file names. I don't know for sure, but I would guess the opposite, simply because using case-sensitivity requires reading the documentation and changing a registry entry. > But if that's not the reality, then yes, a patch to add a run-time > test for Cygwin will also be welcome. The attached patch attempts to do this for both Cygwin and OS X. I don't have access to an OS X system, so someone else will have to test the OS X part. Ken --------------087F2E76C6F6CE762B53446A Content-Type: text/plain; charset=UTF-8; name="0001-Check-case-sensitivity-when-renaming-files.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-Check-case-sensitivity-when-renaming-files.patch" >From 56a3c8cfe5d1d0e5ade985db0d570b502ffe8bce Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 22 Oct 2016 19:10:18 -0400 Subject: [PATCH] Check case-sensitivity when renaming files * src/fileio.c [DOS_NT || CYGWIN || DARWIN_OS] (file_name_case_insensitive_p, Ffile_name_case_insensitive_p): New functions. (Frename_file): Allow renames that simply change case when the FILE argument is on a case-insensitive filesystem. (Bug#24441) * lisp/dired-aux.el (dired-do-create-files): Use 'file-name-case-insensitive-p' instead of 'system-type' to check for case-insensitivity. (Bug#24441) --- lisp/dired-aux.el | 15 ++++++----- src/fileio.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 15 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index d25352e..7f0ab78 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -1799,13 +1799,16 @@ dired-do-create-files (concat (if dired-one-file op1 operation) " %s to: ") target-dir op-symbol arg rfn-list default)))) (into-dir (cond ((null how-to) - ;; Allow DOS/Windows users to change the letter - ;; case of a directory. If we don't test these - ;; conditions up front, file-directory-p below - ;; will return t because the filesystem is - ;; case-insensitive, and Emacs will try to move + ;; Allow users to change the letter case of + ;; a directory on a case-insensitive + ;; filesystem. If we don't test these + ;; conditions up front, file-directory-p + ;; below will return t on a case-insensitive + ;; filesystem, and Emacs will try to move ;; foo -> foo/foo, which fails. - (if (and (memq system-type '(ms-dos windows-nt cygwin)) + (if (and (fboundp 'file-name-case-insensitive-p) + (file-name-case-insensitive-p + (expand-file-name (car fn-list))) (eq op-symbol 'move) dired-one-file (string= (downcase diff --git a/src/fileio.c b/src/fileio.c index 6026d8e..a5a6547 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -25,6 +25,10 @@ along with GNU Emacs. If not, see . */ #include #include +#ifdef DARWIN_OS +#include +#endif + #ifdef HAVE_PWD_H #include #endif @@ -2231,6 +2235,50 @@ internal_delete_file (Lisp_Object filename) return NILP (tem); } +/* Filesystems are always case-insensitive on MS-Windows and MS-DOS. + They may or may not be case-insensitive on Cygwin and OS X, so we + need a runtime test, if possible. If a test is not available, + assume case-insensitivity on Cygwin and case-sensitivity on OS X. */ +#if defined DOS_NT || defined CYGWIN || defined DARWIN_OS +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 + return pathconf (filename, _PC_CASE_INSENSITIVE) > 0; +# else + return 1; +# endif +# else /* 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); +# endif /* DARWIN_OS */ +} + +DEFUN ("file-name-case-insensitive-p", Ffile_name_case_insensitive_p, + Sfile_name_case_insensitive_p, 1, 1, 0, + doc: /* Return t if file FILENAME is on a case-insensitive filesystem. +The arg must be a string. */) + (Lisp_Object filename) +{ + CHECK_STRING (filename); + return file_name_case_insensitive_p (SSDATA (filename)) ? Qt : Qnil; +} +#endif /* DOS_NT or CYGWIN or DARWIN_OS */ + DEFUN ("rename-file", Frename_file, Srename_file, 2, 3, "fRename file: \nGRename %s to file: \np", doc: /* Rename FILE as NEWNAME. Both args must be strings. @@ -2250,10 +2298,12 @@ This is what happens in interactive use with M-x. */) file = Fexpand_file_name (file, Qnil); if ((!NILP (Ffile_directory_p (newname))) -#ifdef DOS_NT - /* If the file names are identical but for the case, - don't attempt to move directory to itself. */ - && (NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))) +#if defined DOS_NT || defined CYGWIN || defined DARWIN_OS + /* If the filesystem is case-insensitive and the file names are + identical but for the case, don't attempt to move directory + to itself. */ + && (NILP (Ffile_name_case_insensitive_p (file)) + || NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))) #endif ) { @@ -2276,11 +2326,12 @@ This is what happens in interactive use with M-x. */) encoded_file = ENCODE_FILE (file); encoded_newname = ENCODE_FILE (newname); -#ifdef DOS_NT - /* If the file names are identical but for the case, don't ask for - confirmation: they simply want to change the letter-case of the - file name. */ - if (NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))) +#if defined DOS_NT || defined CYGWIN || defined DARWIN_OS + /* If the filesystem is case-insensitive and the file names are + identical but for the case, don't ask for confirmation: they + simply want to change the letter-case of the file name. */ + if (NILP (Ffile_name_case_insensitive_p (file)) + || NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))) #endif if (NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists)) @@ -5836,6 +5887,9 @@ syms_of_fileio (void) DEFSYM (Qmake_directory_internal, "make-directory-internal"); DEFSYM (Qmake_directory, "make-directory"); DEFSYM (Qdelete_file, "delete-file"); +#if defined DOS_NT || defined CYGWIN || defined DARWIN_OS + DEFSYM (Qfile_name_case_insensitive_p, "file-name-case-insensitive-p"); +#endif DEFSYM (Qrename_file, "rename-file"); DEFSYM (Qadd_name_to_file, "add-name-to-file"); DEFSYM (Qmake_symbolic_link, "make-symbolic-link"); @@ -6093,6 +6147,9 @@ This includes interactive calls to `delete-file' and defsubr (&Smake_directory_internal); defsubr (&Sdelete_directory_internal); defsubr (&Sdelete_file); +#if defined DOS_NT || defined CYGWIN || defined DARWIN_OS + defsubr (&Sfile_name_case_insensitive_p); +#endif defsubr (&Srename_file); defsubr (&Sadd_name_to_file); defsubr (&Smake_symbolic_link); -- 2.8.3 --------------087F2E76C6F6CE762B53446A--