diff options
Diffstat (limited to 'swap.c')
-rw-r--r-- | swap.c | 51 |
1 files changed, 51 insertions, 0 deletions
@@ -0,0 +1,51 @@ +/* Rename two files atomically, swapping one for the other. + * Copyright (C) 2015 Peter Wu <peter@lekensteyn.nl> + */ + +#define _GNU_SOURCE +#include <unistd.h> +#include <sys/syscall.h> +#include <linux/fs.h> /* for RENAME_* */ +#include <fcntl.h> /* for AT_* */ +#include <stdio.h> +#include <errno.h> + +int renameat2(int olddirfd, const char *oldpath, + int newdirfd, const char *newpath, unsigned int flags) +{ + long r; + r = syscall(SYS_renameat2, olddirfd, oldpath, newdirfd, newpath, flags); + return (int)r; +} + +int main(int argc, char **argv) +{ + int olddirfd, newdirfd; + const char *oldpath, *newpath; + unsigned flags; + int r; + + if (argc - 1 < 2) { + fprintf(stderr, "Usage: %s file1 file2\n", argv[0]); + fprintf(stderr, "Atomically swaps file1 and file2.\n"); + return 1; + } + + olddirfd = AT_FDCWD; + newdirfd = AT_FDCWD; + oldpath = argv[1]; + newpath = argv[2]; + flags = RENAME_EXCHANGE; + + r = renameat2(olddirfd, oldpath, newdirfd, newpath, flags); + if (r < 0) { + if (errno == ENOSYS) { + fprintf(stderr, "renameat2 syscall not available!" + " You need Linux 3.15 or newer.\n"); + } else { + perror("renameat2 failed"); + } + } + + return r < 0 ? 1 : 0; +} |