2 * Copyright (c) 2014, Miklos Szeredi <mszeredi@suse.cz>
3 * This file is published under GPL2+.
5 * This is a trivial wrapper around the renameat2 syscall.
10 #ifndef HAVE_RENAMEAT2
11 #include <sys/syscall.h>
13 #if !defined(SYS_renameat2) && defined(__x86_64__)
14 #define SYS_renameat2 316
17 #if !defined(SYS_renameat2) && defined(__i386__)
18 #define SYS_renameat2 353
21 #if !defined(SYS_renameat2) && defined(__i386__)
22 #define SYS_renameat2 353
25 static int renameat2(int dfd1, const char *path1,
26 int dfd2, const char *path2,
30 return syscall(SYS_renameat2, dfd1, path1, dfd2, path2, flags);
38 #ifndef RENAME_NOREPLACE
39 #define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */
41 #ifndef RENAME_EXCHANGE
42 #define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
44 #ifndef RENAME_WHITEOUT
45 #define RENAME_WHITEOUT (1 << 2) /* Whiteout source */
48 int main(int argc, char *argv[])
52 const char *path1 = NULL;
53 const char *path2 = NULL;
54 unsigned int flags = 0;
57 for (c = 1; c < argc; c++) {
58 if (argv[c][0] == '-') {
64 flags |= RENAME_NOREPLACE;
67 flags |= RENAME_EXCHANGE;
70 flags |= RENAME_WHITEOUT;
84 if (!test && (!path1 || !path2))
87 ret = renameat2(AT_FDCWD, path1, AT_FDCWD, path2, flags);
90 if (errno == ENOSYS || errno == EINVAL)
96 * Turn EEXIST into ENOTEMPTY. E.g. XFS uses EEXIST, and that
97 * is also accepted by the standards.
99 * This applies only to plain rename and RENAME_WHITEOUT
101 if (errno == EEXIST && (!flags || (flags & RENAME_WHITEOUT)))
112 "usage: %s [-t] [-n|-x|-w] path1 path2\n"
116 " -w whiteout\n", argv[0]);