summaryrefslogtreecommitdiff
path: root/src/renameat2.c
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2014-04-14 10:34:51 +1000
committerDave Chinner <david@fromorbit.com>2014-04-14 10:34:51 +1000
commit413f501b5325db07389ac40f7f6939abb3eb8b79 (patch)
treed205730b3f851e452fd33e5c44189592ff5145c2 /src/renameat2.c
parenta0e2d8ecc0ed2fd44e94814e43064c86734733ee (diff)
common: add infrastructure for renameat2 syscall tests
The renameat2() syscall was merged into 3.15-rc (merge commit: 7df934526c0b). This adds the shared infrastructure for the actual test scripts. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'src/renameat2.c')
-rw-r--r--src/renameat2.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/renameat2.c b/src/renameat2.c
new file mode 100644
index 00000000..51459597
--- /dev/null
+++ b/src/renameat2.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, Miklos Szeredi <mszeredi@suse.cz>
+ * This file is published under GPL2+.
+ *
+ * This is a trivial wrapper around the renameat2 syscall.
+ */
+
+#include "global.h"
+
+#ifndef HAVE_RENAMEAT2
+#include <sys/syscall.h>
+
+#if !defined(SYS_renameat2) && defined(__x86_64__)
+#define SYS_renameat2 316
+#endif
+
+static int renameat2(int dfd1, const char *path1,
+ int dfd2, const char *path2,
+ unsigned int flags)
+{
+#ifdef SYS_renameat2
+ return syscall(SYS_renameat2, dfd1, path1, dfd2, path2, flags);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+#endif
+
+#ifndef RENAME_NOREPLACE
+#define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */
+#endif
+#ifndef RENAME_EXCHANGE
+#define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
+#endif
+#ifndef RENAME_WHITEOUT
+#define RENAME_WHITEOUT (1 << 2) /* Whiteout source */
+#endif
+
+int main(int argc, char *argv[])
+{
+ int ret;
+ int c;
+ const char *path1 = NULL;
+ const char *path2 = NULL;
+ unsigned int flags = 0;
+ int test = 0;
+
+ for (c = 1; c < argc; c++) {
+ if (argv[c][0] == '-') {
+ switch (argv[c][1]) {
+ case 't':
+ test = 1;
+ break;
+ case 'n':
+ flags |= RENAME_NOREPLACE;
+ break;
+ case 'x':
+ flags |= RENAME_EXCHANGE;
+ break;
+ case 'w':
+ flags |= RENAME_WHITEOUT;
+ break;
+ default:
+ goto usage;
+ }
+ } else if (!path1) {
+ path1 = argv[c];
+ } else if (!path2) {
+ path2 = argv[c];
+ } else {
+ goto usage;
+ }
+ }
+
+ if (!test && (!path1 || !path2))
+ goto usage;
+
+ ret = renameat2(AT_FDCWD, path1, AT_FDCWD, path2, flags);
+ if (ret == -1) {
+ if (test) {
+ if (errno == ENOSYS || errno == EINVAL)
+ return 1;
+ else
+ return 0;
+ }
+ perror("");
+ return 1;
+ }
+
+ return 0;
+
+usage:
+ fprintf(stderr,
+ "usage: %s [-t] [-n|-x|-w] path1 path2\n"
+ " -t test\n"
+ " -n noreplace\n"
+ " -x exchange\n"
+ " -w whiteout\n", argv[0]);
+
+ return 1;
+}