Hi, The renameat2 function is "Linux-specific", says the man page [1]; however, Cygwin implements it as well.
In Cygwin 3.4.6, in a specific case, it operates differently than the Linux function. Namely, if the old* arguments and the new* arguments are the same and the flag RENAME_NOREPLACE is specified. How to reproduce: ================================ foo.c ================================ #ifdef __CYGWIN__ #include <cygwin/fs.h> #else #define _GNU_SOURCE 1 #ifdef __linux__ # include <sys/syscall.h> #endif #endif #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/stat.h> int main (void) { system ("rm -rf sub2"); int dfd = open (".", O_RDONLY); if (dfd < 0) perror ("open"); int ret = mkdir ("sub2", 0700); if (ret < 0) perror ("mkdir"); close (creat ("sub2/file", 0600)); #if defined __CYGWIN__ || defined __GLIBC__ ret = renameat2 (dfd, "sub2/file", dfd, "sub2/file", RENAME_NOREPLACE); #else /* musl libc */ ret = syscall (SYS_renameat2, dfd, "sub2/file", dfd, "sub2/file", 1); #endif if (ret >= 0) printf ("ret=%d\n", ret); else printf ("ret=%d, errno=%d%s\n", ret, errno, errno == EEXIST ? "=EEXIST" : ""); } =============================================================================== Output on Linux (glibc, musl libc): ret=-1, errno=17=EEXIST Output on Cygwin 3.4.6: ret=0 Note that there is some ambiguity about this case in [1]: One one hand, there is the general statement about rename(): "If oldpath and newpath are existing hard links referring to the same file, then rename() does nothing, and returns a success status." On the other hand, the text regarding RENAME_NOREPLACE says: "Return an error if newpath already exists." Bruno [1] https://man7.org/linux/man-pages/man2/rename.2.html -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple