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.

``