This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

renameat2


Linux has a system call 'renameat2' which is like renameat but has an extra 'flags' argument.  In particular, one can pass the RENAME_NOREPLACE flag to cause the rename to fail with EEXIST if the target of the rename exists.  See

 http://man7.org/linux/man-pages/man2/rename.2.html

macOS has a similar functionality, provided by the function 'renameatx_np' with the flag RENAME_EXCL.

There's also a recently introduced Gnulib module 'renameat2', but it requires two system calls on Cygwin (one to test existence and the second to do the rename), so that there is a race condition.  On Linux and macOS it uses renameat2 and renameatx_np to avoid the race.

The attached patch implements renameat2 on Cygwin (but only supporting the RENAME_NOREPLACE flag).  I've written it so that a rename that just changes case on a case-insensitive file system succeeds.

If the patch is accepted, I'll submit a second patch that documents the new function.

Here's a simple test program:

$ cat rename_noreplace.c
#include <fcntl.h>
#include <stdio.h>
#include <cygwin/fs.h>

int
main ()
{
 int res = renameat2 (AT_FDCWD, "foo", AT_FDCWD, "bar", RENAME_NOREPLACE);
 if (res < 0)
   perror ("renameat2");
}

$ gcc -o rename_noreplace rename_noreplace.c

$ touch foo bar

$ ./rename_noreplace.exe
renameat2: File exists

$ ls foo bar
bar  foo

$ rm bar

$ ./rename_noreplace.exe

$ ls foo bar
ls: cannot access 'foo': No such file or directory
bar

Ken

Attachment: 0001-cygwin-Implement-renameat2.patch
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]