从 Linux 3.15 开始,新的renameat2
系统调用可以原子地交换同一文件系统上的两条路径。然而,它甚至还没有一个 glibc 包装器,更不用说使用 coreutils 方法来访问它了。所以它看起来像这样:
int dirfd = open(".../base", O_PATH | O_DIRECTORY | O_CLOEXEC);
syscall(SYS_renameat2, dirfd, "alpha", dirfd, "bravo", RENAME_EXCHANGE);
close(dirfd);
system("rm -rf alpha");
(当然,您应该进行适当的错误处理等 - 请参阅此要点以获得更复杂的renameat2
包装器。)
也就是说 - 其他人提到的符号链接解决方案更容易和可移植,所以除非bravo
已经存在并且您必须自动更新它,否则请改用符号链接。
2020 年更新:自 2018 年 8 月 1 日发布的 glibc 2.28(Debian Stretch,Fedora 29)以来,此系统调用的 glibc 包装器可用。不过,它仍然无法通过 coreutils 访问。
int dirfd = open(".../base", O_PATH | O_DIRECTORY | O_CLOEXEC);
renameat2(dirfd, "alpha", dirfd, "bravo", RENAME_EXCHANGE);
close(dirfd);
system("rm -rf alpha");