From unknown Mon Jun 23 02:21:16 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#27986 <27986@debbugs.gnu.org> To: bug#27986 <27986@debbugs.gnu.org> Subject: Status: 26.0.50; `rename-file' can rename files without confirmation Reply-To: bug#27986 <27986@debbugs.gnu.org> Date: Mon, 23 Jun 2025 09:21:16 +0000 retitle 27986 26.0.50; `rename-file' can rename files without confirmation reassign 27986 emacs submitter 27986 Philipp
Getting back to Philipp's original bug report, Apple docu= mentation says macOS
has a facility like the Linux renameat2 system call (i.e., it's like = 39;renameat'
except it can be told to fail if the destination already exists). Attached = is a
proposed patch to use this facility, which means that the case-insensitivit= y
test would no longer need to be done in macOS. If there's some way to i= mplement
renameat_noreplace on MS-Windows we could get rid of the case-insensitivity= test
there too.
I don't have easy access to macOS so I have not installed this patch. I= t'd be
nice, Philipp, if you could try it out.
RENAME_EXCL
I interpret this such that if the filesystem doesn't su= pport RENAME_EXCL the rename will succeed even if the destination exists.= p>
Since we probably won't be able to solve = all issues across operating systems and filesystems, probably we should hav= e at least a warning in the documentation that rename-file attempts to be r= ace-free and atomic, but only on a best-effort basis.
> From: Paul Eggert <eggert@cs.ucla.edu>
> Cc: Eli Zaretskii <eliz@gnu.org>, 27986@debbugs.gnu.org
> Date: Sun, 13 Aug 2017 16:48:59 -0700
>
> Getting back to Philipp's original bug report, Apple documentation= says macOS
> has a facility like the Linux renameat2 system call (i.e., it's li= ke 'renameat'
> except it can be told to fail if the destination already exists). Atta= ched is a
> proposed patch to use this facility, which means that the case-insensi= tivity
> test would no longer need to be done in macOS. If there's some way= to implement
> renameat_noreplace on MS-Windows we could get rid of the case-insensit= ivity test
> there too.
There's nothing easier than implementing renameat_noreplace on
MS-Windows, since the underlying system call does that by default, and
it's emulating the Posix behavior that requires complications.You might be able to eliminate these complicati= ons by calling MoveFileExW with MOVEFILE_REPLACE_EXISTING.
> From: Philipp <p.stephani2@gmail.com>
> Date: Sun, 06 Aug 2017 17:40:18 +0200
>
> (rename-file "/tmp/emacs/=E1=BA=9E" "/tmp/emacs/=C3=9F&= quot;)
> nil
>
> Note how `rename-file' has silently overwritten `=C3=9F'.=C2= =A0 This is because on
> macOS, `=C3=9F' and `=E1=BA=9E' are different file names, but = Emacs treats them as
> equal.=C2=A0 Probably the test for case-insensitive file names should = be
> removed altogether
Which one? there are two of them.
> (it can't work correctly and introduces a filesystem race)
It cannot work correctly _because_ of a possible race or because of
some other reasons?=C2=A0 If the latter, please elaborate.=C2=A0As this example shows, there are cases where two case= -insensitive filenames are considered equivalent by Emacs, but different by= the actual filesystem. This is unavoidable, because the definition of &quo= t;case-insensitive" changes all the time, both in Emacs and in the fil= esystems. Generally it's impossible to detect whether two filenames wou= ld refer to the same file without actually creating the file. And even then= the answer depends on how the file is created, see e.g. FILE_FLAG_POSIX_SE= MANTICS. So Emacs can't compare filenames and make decisions based on t= he result upon which the correctness of a critical function depends. Compar= ing filenames can still be OK for best-effort attempts at giving the user b= etter error messages or similar.=C2=A0If the former,
then at least on MS-Windows we have a race anyway, because the
underlying system APIs are not atomic.Woul= dn't MoveFileExW with MOVE_FILE_REPLACE_EXISTING be atomic?<= br>> and `rename-file' should use link(2) + unlink(2) if renameat2
> isn't available.
'link' and 'unlink' accept strings as arguments, not intege= r numbers
such as 2.Yes, I mean the functions de= scribed in section 2 of the man page. link(2) is a common markup for this.<= /div>--001a1143b6f2ca0ca40556b9ba63-- From debbugs-submit-bounces@debbugs.gnu.org Mon Aug 14 13:22:28 2017 Received: (at 27986) by debbugs.gnu.org; 14 Aug 2017 17:22:28 +0000 Received: from localhost ([127.0.0.1]:36018 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from=C2=A0
More to the point, how can this strategy work on a case-insensitive
filesystem?=C2=A0 What am I missing?II= UC link(2) + unlink(2) would, if successful, guarantee enough atomicity in = the sense that the old file is now guaranteed to be the new file, and the c= all is guaranteed to fail if the new file already exists. I don't think= anything can help with the case-changing problem; I think we just have to = live with an occasional false positive signal in this case.=C2=A0) id 1dhJ4N-0005S9-ON for submit@debbugs.gnu.org; Mon, 14 Aug 2017 13:22:27 -0400 Received: from eggs.gnu.org ([208.118.235.92]:56491) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dhJ4M-0005S3-1x for 27986@debbugs.gnu.org; Mon, 14 Aug 2017 13:22:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dhJ4B-0003UK-VF for 27986@debbugs.gnu.org; Mon, 14 Aug 2017 13:22:20 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,RP_MATCHES_RCVD autolearn=disabled version=3.3.2 Received: from fencepost.gnu.org ([2001:4830:134:3::e]:36949) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dhJ4B-0003UE-Rc; Mon, 14 Aug 2017 13:22:15 -0400 Received: from 84.94.185.246.cable.012.net.il ([84.94.185.246]:4832 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from