diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2014-04-14 10:34:51 +1000 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-04-14 10:34:51 +1000 |
commit | 413f501b5325db07389ac40f7f6939abb3eb8b79 (patch) | |
tree | d205730b3f851e452fd33e5c44189592ff5145c2 /src/renameat2.c | |
parent | a0e2d8ecc0ed2fd44e94814e43064c86734733ee (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.c | 102 |
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; +} |