Skip to content

Commit

Permalink
Use rename/unlink/etc. instead of renameat/unlinkat`/etc. (#247)
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
sunfishcode authored Aug 6, 2023
1 parent d258544 commit a5c236c
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions src/file/imp/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<File> {
open_options.read(true).write(true).create_new(true);
Expand Down Expand Up @@ -103,13 +106,13 @@ pub fn reopen(_file: &File, _path: &Path) -> io::Result<File> {
#[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};

Expand All @@ -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(())
}
Expand Down

0 comments on commit a5c236c

Please sign in to comment.