Subject: bug#27986: 26.0.50; 'rename-file' can rename files without confirmation

From: Ken Brown <[email-masked]>
Date: Sat, 19 Aug 2017 17:30:01 -0400

On 8/16/2017 3:33 PM, Ken Brown wrote:
> On 8/14/2017 7:03 PM, Paul Eggert wrote
>> Now that renameat_noreplace works on DOS_NT, would it make sense to 
>> apply the attached further patch as well? If we can get 
>> renameat_noreplace to work on Cygwin the we could simplify the 
>> fileio.c code even further.
> 
> I'm in the process of writing an implementation of something like 
> 'renameat2', which I'll submit to the Cygwin developers.

This is now done.  The implementation will appear in the next Cygwin 
release.  When that release occurs, I'll install something like the 
attached patch.

Question: Is the patch OK as is, or should I make the call to renameat2 
conditional on CYGWIN?  In other words, is it safe to assume that 
renameat2 is defined on any platform on which RENAME_NOREPLACE is 
defined but not SYS_renameat2?

Ken

From b9ef4ca995350d1a520aba66de1d5e4209f3eb91 Mon Sep 17 00:00:00 2001
From: Ken Brown <[email-masked]>
Date: Sat, 19 Aug 2017 17:17:27 -0400
Subject: [PATCH] Implement renameat_noreplace on recent Cygwin

* src/sysdep.c [CYGWIN]: Include cygwin/fs.h.
(renameat_noreplace) [RENAME_NOREPLACE]: Use renameat2.
(Bug#27986)
---
 src/sysdep.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/sysdep.c b/src/sysdep.c
index 12e9c83ee9..77221097db 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -42,6 +42,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 # include <sys/syscall.h>
 #endif
 
+#ifdef CYGWIN
+# include <cygwin/fs.h>
+#endif
+
 #if defined DARWIN_OS || defined __FreeBSD__
 # include <sys/sysctl.h>
 #endif
@@ -2685,6 +2689,8 @@ renameat_noreplace (int srcfd, char const *src, int dstfd, char const *dst)
 {
 #if defined SYS_renameat2 && defined RENAME_NOREPLACE
   return syscall (SYS_renameat2, srcfd, src, dstfd, dst, RENAME_NOREPLACE);
+#elif defined RENAME_NOREPLACE	/* Cygwin >= 2.9.0. */
+  return renameat2 (srcfd, src, dstfd, dst, RENAME_NOREPLACE);
 #elif defined RENAME_EXCL
   return renameatx_np (srcfd, src, dstfd, dst, RENAME_EXCL);
 #else
-- 
2.14.1