162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Program that atomically exchanges two paths using
462306a36Sopenharmony_ci * the renameat2() system call RENAME_EXCHANGE flag.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright 2022 Red Hat Inc.
762306a36Sopenharmony_ci * Author: Javier Martinez Canillas <javierm@redhat.com>
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#define _GNU_SOURCE
1162306a36Sopenharmony_ci#include <fcntl.h>
1262306a36Sopenharmony_ci#include <stdio.h>
1362306a36Sopenharmony_ci#include <stdlib.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_civoid print_usage(const char *program)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	printf("Usage: %s [oldpath] [newpath]\n", program);
1862306a36Sopenharmony_ci	printf("Atomically exchange oldpath and newpath\n");
1962306a36Sopenharmony_ci}
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ciint main(int argc, char *argv[])
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	int ret;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	if (argc != 3) {
2662306a36Sopenharmony_ci		print_usage(argv[0]);
2762306a36Sopenharmony_ci		exit(EXIT_FAILURE);
2862306a36Sopenharmony_ci	}
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci	ret = renameat2(AT_FDCWD, argv[1], AT_FDCWD, argv[2], RENAME_EXCHANGE);
3162306a36Sopenharmony_ci	if (ret) {
3262306a36Sopenharmony_ci		perror("rename exchange failed");
3362306a36Sopenharmony_ci		exit(EXIT_FAILURE);
3462306a36Sopenharmony_ci	}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	exit(EXIT_SUCCESS);
3762306a36Sopenharmony_ci}
38