std::unix::fs: copy simplification for apple. · model-checking/verify-rust-std@d688595
@@ -20,14 +20,14 @@ use crate::sys::time::SystemTime;
2020use crate::sys::{cvt, cvt_r};
2121use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
222223-#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
23+#[cfg(all(target_os = "linux", target_env = "gnu"))]
2424use crate::sys::weak::syscall;
2525#[cfg(target_os = "android")]
2626use crate::sys::weak::weak;
27272828use libc::{c_int, mode_t};
292930-#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
30+#[cfg(all(target_os = "linux", target_env = "gnu"))]
3131use libc::c_char;
3232#[cfg(any(
3333 all(target_os = "linux", not(target_env = "musl")),
@@ -1891,8 +1891,6 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
1891189118921892#[cfg(target_vendor = "apple")]
18931893pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
1894-use crate::sync::atomic::{AtomicBool, Ordering};
1895-18961894const COPYFILE_ALL: libc::copyfile_flags_t = libc::COPYFILE_METADATA | libc::COPYFILE_DATA;
1897189518981896struct FreeOnDrop(libc::copyfile_state_t);
@@ -1907,39 +1905,21 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
19071905}
19081906}
190919071910-// MacOS prior to 10.12 don't support `fclonefileat`
1911-// We store the availability in a global to avoid unnecessary syscalls
1912-static HAS_FCLONEFILEAT: AtomicBool = AtomicBool::new(true);
1913-syscall! {
1914-// Mirrors `libc::fclonefileat`
1915-fn fclonefileat(
1916- srcfd: libc::c_int,
1917- dst_dirfd: libc::c_int,
1918- dst: *const c_char,
1919- flags: libc::c_int
1920-) -> libc::c_int
1921-}
1922-19231908let (reader, reader_metadata) = open_from(from)?;
192419091925-// Opportunistically attempt to create a copy-on-write clone of `from`
1926-// using `fclonefileat`.
1927-if HAS_FCLONEFILEAT.load(Ordering::Relaxed) {
1928-let clonefile_result = run_path_with_cstr(to, &|to| {
1929-cvt(unsafe { fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) })
1930-});
1931-match clonefile_result {
1932-Ok(_) => return Ok(reader_metadata.len()),
1933-Err(err) => match err.raw_os_error() {
1934-// `fclonefileat` will fail on non-APFS volumes, if the
1935-// destination already exists, or if the source and destination
1936-// are on different devices. In all these cases `fcopyfile`
1937-// should succeed.
1938-Some(libc::ENOTSUP) | Some(libc::EEXIST) | Some(libc::EXDEV) => (),
1939-Some(libc::ENOSYS) => HAS_FCLONEFILEAT.store(false, Ordering::Relaxed),
1940- _ => return Err(err),
1941-},
1942-}
1910+let clonefile_result = run_path_with_cstr(to, &|to| {
1911+cvt(unsafe { libc::fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) })
1912+});
1913+match clonefile_result {
1914+Ok(_) => return Ok(reader_metadata.len()),
1915+Err(e) => match e.raw_os_error() {
1916+// `fclonefileat` will fail on non-APFS volumes, if the
1917+// destination already exists, or if the source and destination
1918+// are on different devices. In all these cases `fcopyfile`
1919+// should succeed.
1920+Some(libc::ENOTSUP) | Some(libc::EEXIST) | Some(libc::EXDEV) => (),
1921+ _ => return Err(e),
1922+},
19431923}
1944192419451925// Fall back to using `fcopyfile` if `fclonefileat` does not succeed.