diff options
| author | bors <bors@rust-lang.org> | 2019-03-16 14:46:43 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-03-16 14:46:43 +0000 |
| commit | 2c8bbf50db0ef90a33f986ba8fc2e1fe129197ff (patch) | |
| tree | 0d1a620d973a7dff4f6ca02a51bdd3e4814ba5c9 /src/libstd/sys/unix | |
| parent | 52e885628e4317aa3f158622435927eb29b812e9 (diff) | |
| parent | 7c009a4df7214290e6e5cf73d5bd5652fa8015dc (diff) | |
| download | rust-2c8bbf50db0ef90a33f986ba8fc2e1fe129197ff.tar.gz rust-2c8bbf50db0ef90a33f986ba8fc2e1fe129197ff.zip | |
Auto merge of #59226 - kennytm:rollup, r=kennytm
Rollup of 37 pull requests Successful merges: - #58854 (appveyor: Use VS2017 for all our images) - #58855 (std: Spin for a global malloc lock on wasm32) - #58873 (Fix "Auto-hide item methods documentation" setting) - #58901 (Change `std::fs::copy` to use `copyfile` on MacOS and iOS) - #58933 (Move alloc::prelude::* to alloc::prelude::v1, make alloc a subset of std) - #58938 (core: ensure VaList passes improper_ctypes lint) - #58941 (MIPS: add r6 support) - #58949 (SGX target: Expose thread id function in os module) - #58959 (Add release notes for PR #56243) - #58976 (Default to integrated `rust-lld` linker for UEFI targets) - #59009 (Fix SGX implementations of read/write_vectored.) - #59025 (Fix generic argument lookup for Self) - #59036 (Fix ICE in MIR pretty printing) - #59037 (Avoid some common false positives in intra doc link checking) - #59072 (we can now skip should_panic tests with the libtest harness) - #59079 (add suggestions to invalid macro item error) - #59082 (A few improvements to comments in user-facing crates) - #59102 (Consistent naming for duration_float methods and additional f32 methods) - #59118 (rustc: fix ICE when trait alias has bare Self) - #59139 (Unregress using scalar unions in constants.) - #59146 (Suggest return lifetime when there's only one named lifetime) - #59147 (Make std time tests more robust for platform differences) - #59152 (Stabilize Range*::contains.) - #59156 ([wg-async-await] Add regression test for #55809.) - #59158 (Revert "Don't generate minification variable if minification disabled") - #59169 (Add `-Z allow_features=...` flag) - #59173 (bootstrap: Default to a sensible llvm-suffix.) - #59175 (Don't run test launching `echo` since that doesn't exist on Windows) - #59180 (Use try blocks in rustc_codegen_ssa) - #59185 (No old chestnuts in iter::repeat docs) - #59201 (Remove restriction on isize/usize in repr(simd)) - #59204 (Output diagnostic information for rustdoc) - #59206 (Improved test output) - #59208 (Reduce a Code Repetition Related to Bit Operation) - #59212 (Add x86_64 musl host to the manifest) - #59221 (Option and Result: Add references to documentation of as_ref and as_mut) - #59231 (Stabilize Option::copied)
Diffstat (limited to 'src/libstd/sys/unix')
| -rw-r--r-- | src/libstd/sys/unix/fs.rs | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 3b80b475a93..7ff098bc9e1 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -827,7 +827,10 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> { Ok(PathBuf::from(OsString::from_vec(buf))) } -#[cfg(not(any(target_os = "linux", target_os = "android")))] +#[cfg(not(any(target_os = "linux", + target_os = "android", + target_os = "macos", + target_os = "ios")))] pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { use crate::fs::File; if !from.is_file() { @@ -937,3 +940,85 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { writer.set_permissions(perm)?; Ok(written) } + +#[cfg(any(target_os = "macos", target_os = "ios"))] +pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { + const COPYFILE_ACL: u32 = 1 << 0; + const COPYFILE_STAT: u32 = 1 << 1; + const COPYFILE_XATTR: u32 = 1 << 2; + const COPYFILE_DATA: u32 = 1 << 3; + + const COPYFILE_SECURITY: u32 = COPYFILE_STAT | COPYFILE_ACL; + const COPYFILE_METADATA: u32 = COPYFILE_SECURITY | COPYFILE_XATTR; + const COPYFILE_ALL: u32 = COPYFILE_METADATA | COPYFILE_DATA; + + const COPYFILE_STATE_COPIED: u32 = 8; + + #[allow(non_camel_case_types)] + type copyfile_state_t = *mut libc::c_void; + #[allow(non_camel_case_types)] + type copyfile_flags_t = u32; + + extern "C" { + fn copyfile( + from: *const libc::c_char, + to: *const libc::c_char, + state: copyfile_state_t, + flags: copyfile_flags_t, + ) -> libc::c_int; + fn copyfile_state_alloc() -> copyfile_state_t; + fn copyfile_state_free(state: copyfile_state_t) -> libc::c_int; + fn copyfile_state_get( + state: copyfile_state_t, + flag: u32, + dst: *mut libc::c_void, + ) -> libc::c_int; + } + + struct FreeOnDrop(copyfile_state_t); + impl Drop for FreeOnDrop { + fn drop(&mut self) { + // The code below ensures that `FreeOnDrop` is never a null pointer + unsafe { + // `copyfile_state_free` returns -1 if the `to` or `from` files + // cannot be closed. However, this is not considerd this an + // error. + copyfile_state_free(self.0); + } + } + } + + if !from.is_file() { + return Err(Error::new(ErrorKind::InvalidInput, + "the source path is not an existing regular file")) + } + + // We ensure that `FreeOnDrop` never contains a null pointer so it is + // always safe to call `copyfile_state_free` + let state = unsafe { + let state = copyfile_state_alloc(); + if state.is_null() { + return Err(crate::io::Error::last_os_error()); + } + FreeOnDrop(state) + }; + + cvt(unsafe { + copyfile( + cstr(from)?.as_ptr(), + cstr(to)?.as_ptr(), + state.0, + COPYFILE_ALL, + ) + })?; + + let mut bytes_copied: libc::off_t = 0; + cvt(unsafe { + copyfile_state_get( + state.0, + COPYFILE_STATE_COPIED, + &mut bytes_copied as *mut libc::off_t as *mut libc::c_void, + ) + })?; + Ok(bytes_copied as u64) +} |
