std::unix::fs: copy simplification for apple. · model-checking/verify-rust-std@d688595 (original) (raw)
`@@ -20,14 +20,14 @@ use crate::sys::time::SystemTime;
`
20
20
`use crate::sys::{cvt, cvt_r};
`
21
21
`use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
`
22
22
``
23
``
`-
#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
`
``
23
`+
#[cfg(all(target_os = "linux", target_env = "gnu"))]
`
24
24
`use crate::sys::weak::syscall;
`
25
25
`#[cfg(target_os = "android")]
`
26
26
`use crate::sys::weak::weak;
`
27
27
``
28
28
`use libc::{c_int, mode_t};
`
29
29
``
30
``
`-
#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
`
``
30
`+
#[cfg(all(target_os = "linux", target_env = "gnu"))]
`
31
31
`use libc::c_char;
`
32
32
`#[cfg(any(
`
33
33
` all(target_os = "linux", not(target_env = "musl")),
`
`@@ -1891,8 +1891,6 @@ pub fn copy(from: &Path, to: &Path) -> io::Result {
`
1891
1891
``
1892
1892
`#[cfg(target_vendor = "apple")]
`
1893
1893
`pub fn copy(from: &Path, to: &Path) -> io::Result {
`
1894
``
`-
use crate::sync::atomic::{AtomicBool, Ordering};
`
1895
``
-
1896
1894
`const COPYFILE_ALL: libc::copyfile_flags_t = libc::COPYFILE_METADATA | libc::COPYFILE_DATA;
`
1897
1895
``
1898
1896
`struct FreeOnDrop(libc::copyfile_state_t);
`
`@@ -1907,39 +1905,21 @@ pub fn copy(from: &Path, to: &Path) -> io::Result {
`
1907
1905
`}
`
1908
1906
`}
`
1909
1907
``
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
``
-
1923
1908
`let (reader, reader_metadata) = open_from(from)?;
`
1924
1909
``
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
`+
},
`
1943
1923
`}
`
1944
1924
``
1945
1925
`` // Fall back to using fcopyfile
if fclonefileat
does not succeed.
``