From 60274a95fef57a18113f7c48be68be31ece860eb Mon Sep 17 00:00:00 2001 From: Daniel Henry-Mantilla Date: Sun, 1 Sep 2019 17:23:20 +0200 Subject: Added From> for CString Updated tracking issue number Added safeguards for transmute_vec potentially being factored out elsewhere Clarified comment about avoiding mem::forget Removed unneeded unstable guard Added back a stability annotation for CI Minor documentation improvements Thanks to @Centril's code review Co-Authored-By: Mazdak Farrokhzad Improved layout checks, type annotations and removed unaccurate comment Removed unnecessary check on array layout Adapt the stability annotation to the new 1.41 milestone Co-Authored-By: Mazdak Farrokhzad Simplify the implementation. Use `Vec::into_raw_parts` instead of a manual implementation of `Vec::transmute`. If `Vec::into_raw_parts` uses `NonNull` instead, then the code here will need to be adjusted to take it into account (issue #65816) Reduce the whitespace of safety comments --- src/libstd/ffi/c_str.rs | 27 +++++++++++++++++++++++++++ src/libstd/lib.rs | 1 + 2 files changed, 28 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index d2ee65f0a74..217672ea292 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -6,6 +6,7 @@ use crate::fmt::{self, Write}; use crate::io; use crate::mem; use crate::memchr; +use crate::num::NonZeroU8; use crate::ops; use crate::os::raw::c_char; use crate::ptr; @@ -741,6 +742,32 @@ impl From> for CString { } } +#[stable(feature = "cstring_from_vec_of_nonzerou8", since = "1.43.0")] +impl From> for CString { + /// Converts a [`Vec`]`<`[`NonZeroU8`]`>` into a [`CString`] without + /// copying nor checking for inner null bytes. + /// + /// [`CString`]: ../ffi/struct.CString.html + /// [`NonZeroU8`]: ../num/struct.NonZeroU8.html + /// [`Vec`]: ../vec/struct.Vec.html + #[inline] + fn from(v: Vec) -> CString { + unsafe { + // Transmute `Vec` to `Vec`. + let v: Vec = { + // Safety: + // - transmuting between `NonZeroU8` and `u8` is sound; + // - `alloc::Layout == alloc::Layout`. + let (ptr, len, cap): (*mut NonZeroU8, _, _) = Vec::into_raw_parts(v); + Vec::from_raw_parts(ptr.cast::(), len, cap) + }; + // Safety: `v` cannot contain null bytes, given the type-level + // invariant of `NonZeroU8`. + CString::from_vec_unchecked(v) + } + } +} + #[stable(feature = "more_box_slice_clone", since = "1.29.0")] impl Clone for Box { #[inline] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 9e9df5ab9b6..c05ebc7349d 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -310,6 +310,7 @@ #![feature(unboxed_closures)] #![feature(untagged_unions)] #![feature(unwind_attributes)] +#![feature(vec_into_raw_parts)] // NB: the above list is sorted to minimize merge conflicts. #![default_lib_allocator] -- cgit 1.4.1-3-g733a5 From 8fb8bb4b3ff25570a7a9b105c1a569bb2307f25f Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Wed, 12 Feb 2020 19:51:30 +0000 Subject: Fix std::fs::copy on WASI target Previously `std::fs::copy` on wasm32-wasi would reuse code from the `sys_common` module and would successfully copy contents of the file just to fail right before closing it. This was happening because `sys_common::copy` tries to copy permissions of the file, but permissions are not a thing in WASI (at least yet) and `set_permissions` is implemented as an unconditional runtime error. This change instead adds a custom working implementation of `std::fs::copy` (like Rust already has on some other targets) that doesn't try to call `set_permissions` and is essentially a thin wrapper around `std::io::copy`. Fixes #68560. --- src/libstd/sys/wasi/fs.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs index 04bfdf67e12..a11f61fdd69 100644 --- a/src/libstd/sys/wasi/fs.rs +++ b/src/libstd/sys/wasi/fs.rs @@ -12,7 +12,6 @@ use crate::sys::time::SystemTime; use crate::sys::unsupported; use crate::sys_common::FromInner; -pub use crate::sys_common::fs::copy; pub use crate::sys_common::fs::remove_dir_all; pub struct File { @@ -647,3 +646,12 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop, PathBuf)> { pub fn osstr2str(f: &OsStr) -> io::Result<&str> { f.to_str().ok_or_else(|| io::Error::new(io::ErrorKind::Other, "input must be utf-8")) } + +pub fn copy(from: &Path, to: &Path) -> io::Result { + use crate::fs::File; + + let mut reader = File::open(from)?; + let mut writer = File::create(to)?; + + io::copy(&mut reader, &mut writer) +} -- cgit 1.4.1-3-g733a5