Skip to content

Commit 65530ba

Browse files
committed
std::unix::fs: copy simplification for apple.
since we do support from macOs Sierra, we avoid the little runtime overhead with the fclonefileat symbol check.
1 parent 5ced3da commit 65530ba

File tree

1 file changed

+15
-35
lines changed
  • library/std/src/sys/pal/unix

1 file changed

+15
-35
lines changed

library/std/src/sys/pal/unix/fs.rs

+15-35
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ use crate::sys::time::SystemTime;
2020
use crate::sys::{cvt, cvt_r};
2121
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
2222

23-
#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
23+
#[cfg(all(target_os = "linux", target_env = "gnu"))]
2424
use crate::sys::weak::syscall;
2525
#[cfg(target_os = "android")]
2626
use crate::sys::weak::weak;
2727

2828
use libc::{c_int, mode_t};
2929

30-
#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
30+
#[cfg(all(target_os = "linux", target_env = "gnu"))]
3131
use 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> {
18911891

18921892
#[cfg(target_vendor = "apple")]
18931893
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
1894-
use crate::sync::atomic::{AtomicBool, Ordering};
1895-
18961894
const COPYFILE_ALL: libc::copyfile_flags_t = libc::COPYFILE_METADATA | libc::COPYFILE_DATA;
18971895

18981896
struct FreeOnDrop(libc::copyfile_state_t);
@@ -1907,39 +1905,21 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
19071905
}
19081906
}
19091907

1910-
// 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-
19231908
let (reader, reader_metadata) = open_from(from)?;
19241909

1925-
// 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
}
19441924

19451925
// Fall back to using `fcopyfile` if `fclonefileat` does not succeed.

0 commit comments

Comments
 (0)