use std::io;
use std::path::Path;
#[cfg(target_os = "macos")]
pub fn swap_paths(a: &Path, b: &Path) -> io::Result<()> {
use std::ffi::CString;
use std::os::unix::ffi::OsStrExt;
let c_a = CString::new(a.as_os_str().as_bytes())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "path contains a NUL byte"))?;
let c_b = CString::new(b.as_os_str().as_bytes())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "path contains a NUL byte"))?;
let rc = unsafe { libc::renamex_np(c_a.as_ptr(), c_b.as_ptr(), libc::RENAME_SWAP) };
if rc == 0 {
Ok(())
} else {
Err(io::Error::last_os_error())
}
}
#[cfg(not(target_os = "macos"))]
pub fn swap_paths(_a: &Path, _b: &Path) -> io::Result<()> {
Err(io::Error::new(
io::ErrorKind::Unsupported,
"atomic path swap is macOS-only",
))
}
pub fn is_swap_unsupported(error: &io::Error) -> bool {
if error.kind() == io::ErrorKind::Unsupported {
return true;
}
#[cfg(unix)]
if let Some(code) = error.raw_os_error() {
return code == libc::ENOTSUP || code == libc::EINVAL || code == libc::ENOSYS;
}
false
}