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 static int renameat2(int dfd1, const char *path1,
22 int dfd2, const char *path2,
26 return syscall(SYS_renameat2, dfd1, path1, dfd2, path2, flags);
34 #ifndef RENAME_NOREPLACE
35 #define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */
37 #ifndef RENAME_EXCHANGE
38 #define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
40 #ifndef RENAME_WHITEOUT
41 #define RENAME_WHITEOUT (1 << 2) /* Whiteout source */
44 int main(int argc, char *argv[])
48 const char *path1 = NULL;
49 const char *path2 = NULL;
50 unsigned int flags = 0;
53 for (c = 1; c < argc; c++) {
54 if (argv[c][0] == '-') {
60 flags |= RENAME_NOREPLACE;
63 flags |= RENAME_EXCHANGE;
66 flags |= RENAME_WHITEOUT;
80 if (!test && (!path1 || !path2))
83 ret = renameat2(AT_FDCWD, path1, AT_FDCWD, path2, flags);
86 if (errno == ENOSYS || errno == EINVAL)
92 * Turn EEXIST into ENOTEMPTY. E.g. XFS uses EEXIST, and that
93 * is also accepted by the standards.
95 * This applies only to plain rename and RENAME_WHITEOUT
97 if (errno == EEXIST && (!flags || (flags & RENAME_WHITEOUT)))
108 "usage: %s [-t] [-n|-x|-w] path1 path2\n"
112 " -w whiteout\n", argv[0]);