From a5c236ca11fb06373105f65952e194323e9f2637 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sun, 6 Aug 2023 14:37:35 -0700 Subject: [PATCH] Use `rename`/`unlink`/`etc. instead of `renameat`/`unlinkat`/etc. (#247) Rustix on Haiku doesn't support `CWD`, so use the non-`at` versions of functions, since tempfile was only ever passing `CWD` to them. For `link`, switch to `std::fs::hard_link`, since the `link` function has platform-dependent behavior and std has code to deal with that. This should also help portability to some platforms which lack `linkat`. --- src/file/imp/unix.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/file/imp/unix.rs b/src/file/imp/unix.rs index fed4e02e7..79aba783e 100644 --- a/src/file/imp/unix.rs +++ b/src/file/imp/unix.rs @@ -14,7 +14,10 @@ use crate::util; use std::path::Path; #[cfg(not(target_os = "redox"))] -use rustix::fs::{linkat, renameat, unlinkat, AtFlags, CWD}; +use { + rustix::fs::{rename, unlink}, + std::fs::hard_link, +}; pub fn create_named(path: &Path, open_options: &mut OpenOptions) -> io::Result { open_options.read(true).write(true).create_new(true); @@ -103,13 +106,13 @@ pub fn reopen(_file: &File, _path: &Path) -> io::Result { #[cfg(not(target_os = "redox"))] pub fn persist(old_path: &Path, new_path: &Path, overwrite: bool) -> io::Result<()> { if overwrite { - renameat(CWD, old_path, CWD, new_path)?; + rename(old_path, new_path)?; } else { // On Linux, use `renameat_with` to avoid overwriting an existing name, // if the kernel and the filesystem support it. #[cfg(any(target_os = "android", target_os = "linux"))] { - use rustix::fs::{renameat_with, RenameFlags}; + use rustix::fs::{renameat_with, RenameFlags, CWD}; use rustix::io::Errno; use std::sync::atomic::{AtomicBool, Ordering::Relaxed}; @@ -124,12 +127,13 @@ pub fn persist(old_path: &Path, new_path: &Path, overwrite: bool) -> io::Result< } } - // Otherwise use `linkat` to create the new filesystem name, which - // will fail if the name already exists, and then `unlinkat` to remove + // Otherwise use `hard_link` to create the new filesystem name, which + // will fail if the name already exists, and then `unlink` to remove // the old name. - linkat(CWD, old_path, CWD, new_path, AtFlags::empty())?; + hard_link(old_path, new_path)?; + // Ignore unlink errors. Can we do better? - let _ = unlinkat(CWD, old_path, AtFlags::empty()); + let _ = unlink(old_path); } Ok(()) }