Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/renameat2.c
48529 views
// SPDX-License-Identifier: CDDL-1.01/* SPDX-License-Identifier: CDDL-1.0 OR MPL-2.0 */2/*3* CDDL HEADER START4*5* The contents of this file are subject to the terms of the6* Common Development and Distribution License (the "License").7* You may not use this file except in compliance with the License.8*9* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE10* or https://opensource.org/licenses/CDDL-1.0.11* See the License for the specific language governing permissions12* and limitations under the License.13*14* When distributing Covered Code, include this CDDL HEADER in each15* file and include the License file at usr/src/OPENSOLARIS.LICENSE.16* If applicable, add the following below this CDDL HEADER, with the17* fields enclosed by brackets "[]" replaced with your own identifying18* information: Portions Copyright [yyyy] [name of copyright owner]19*20* CDDL HEADER END21*/2223/*24* Copyright (C) 2019 Aleksa Sarai <[email protected]>25* Copyright (C) 2019 SUSE LLC26*/2728/*29* mv(1) doesn't currently support RENAME_{EXCHANGE,WHITEOUT} so this is a very30* simple renameat2(2) wrapper for the OpenZFS self-tests.31*/3233#include <errno.h>34#include <fcntl.h>35#include <unistd.h>36#include <stdio.h>37#include <stdlib.h>38#include <string.h>39#include <sys/syscall.h>4041#ifndef SYS_renameat242#ifdef __NR_renameat243#define SYS_renameat2 __NR_renameat244#elif defined(__x86_64__)45#define SYS_renameat2 31646#elif defined(__i386__)47#define SYS_renameat2 35348#elif defined(__arm__) || defined(__aarch64__)49#define SYS_renameat2 38250#else51#error "SYS_renameat2 not known for this architecture."52#endif53#endif5455#ifndef RENAME_NOREPLACE56#define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */57#endif58#ifndef RENAME_EXCHANGE59#define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */60#endif61#ifndef RENAME_WHITEOUT62#define RENAME_WHITEOUT (1 << 2) /* Whiteout source */63#endif6465/* glibc doesn't provide renameat2 wrapper, let's use our own */66static int67sys_renameat2(int olddirfd, const char *oldpath,68int newdirfd, const char *newpath, unsigned int flags)69{70int ret = syscall(SYS_renameat2, olddirfd, oldpath, newdirfd, newpath,71flags);72return ((ret < 0) ? -errno : ret);73}7475static void76usage(void)77{78fprintf(stderr, "usage: renameat2 [-Cnwx] src dst\n");79exit(1);80}8182static void83check(void)84{85int err = sys_renameat2(AT_FDCWD, ".", AT_FDCWD, ".", RENAME_EXCHANGE);86exit(err == -ENOSYS);87}8889int90main(int argc, char **argv)91{92char *src, *dst;93int ch, err;94unsigned int flags = 0;9596while ((ch = getopt(argc, argv, "Cnwx")) >= 0) {97switch (ch) {98case 'C':99check();100break;101case 'n':102flags |= RENAME_NOREPLACE;103break;104case 'w':105flags |= RENAME_WHITEOUT;106break;107case 'x':108flags |= RENAME_EXCHANGE;109break;110default:111usage();112break;113}114}115116argc -= optind;117argv += optind;118119if (argc != 2)120usage();121src = argv[0];122dst = argv[1];123124err = sys_renameat2(AT_FDCWD, src, AT_FDCWD, dst, flags);125if (err < 0)126fprintf(stderr, "renameat2: %s", strerror(-err));127return (err != 0);128}129130131