From b437157b68dc4752e67c519d920bd183a13683f4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 27 May 2022 07:37:16 -0700 Subject: [PATCH] Remove `ZStr` and `ZString`. (#337) * Remove `ZStr` and `ZString`. Use `CStr` and `CString` instead, now that nightly has then in core and alloc, respectively. Fixes #336. * Enable "core_c_str" on nightly to use core::ffi::CStr. * Don't test --no-default-features on stable. --no-default-features disables "std", and building without "std" will require nightly now. * `CString` and `NulError` are in alloc. * Add comments to the relevant Cargo.toml features. * rustfmt --- .github/workflows/main.yml | 5 +- Cargo.toml | 5 + benches/mod.rs | 4 +- build.rs | 6 +- src/{zstr.rs => cstr.rs} | 36 +- src/ffi/mod.rs | 21 +- src/ffi/z_str.rs | 1748 ------------------------- src/fs/abs.rs | 2 +- src/fs/at.rs | 46 +- src/fs/getpath.rs | 4 +- src/fs/memfd_create.rs | 2 +- src/fs/openat2.rs | 2 +- src/fs/statx.rs | 2 +- src/imp/libc/conv.rs | 4 +- src/imp/libc/fs/dir.rs | 16 +- src/imp/libc/fs/syscalls.rs | 70 +- src/imp/libc/net/addr.rs | 10 +- src/imp/libc/net/read_sockaddr.rs | 4 +- src/imp/libc/process/auxv.rs | 8 +- src/imp/libc/process/syscalls.rs | 4 +- src/imp/libc/termios/syscalls.rs | 4 +- src/imp/libc/weak.rs | 4 +- src/imp/linux_raw/conv.rs | 10 +- src/imp/linux_raw/fs/dir.rs | 12 +- src/imp/linux_raw/fs/syscalls.rs | 78 +- src/imp/linux_raw/net/addr.rs | 10 +- src/imp/linux_raw/process/auxv.rs | 6 +- src/imp/linux_raw/process/syscalls.rs | 4 +- src/imp/linux_raw/runtime/syscalls.rs | 8 +- src/imp/linux_raw/termios/syscalls.rs | 6 +- src/imp/linux_raw/vdso.rs | 12 +- src/imp/linux_raw/vdso_wrappers.rs | 18 +- src/io/procfs.rs | 22 +- src/lib.rs | 16 +- src/path/arg.rs | 369 +++--- src/path/dec_int.rs | 17 +- src/process/auxv.rs | 4 +- src/process/chdir.rs | 10 +- src/process/uname.rs | 18 +- src/runtime.rs | 12 +- src/termios/tty.rs | 8 +- tests/fs/dir.rs | 10 +- tests/fs/openat2.rs | 2 +- tests/net/addr.rs | 10 +- tests/path/arg.rs | 132 +- tests/process/weak.rs | 4 +- 46 files changed, 497 insertions(+), 2308 deletions(-) rename src/{zstr.rs => cstr.rs} (68%) delete mode 100644 src/ffi/z_str.rs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0c35fb965..4bf27863e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -107,11 +107,8 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - build: [stable, nightly] + build: [nightly] include: - - build: stable - os: ubuntu-latest - rust: stable - build: nightly os: ubuntu-latest rust: nightly diff --git a/Cargo.toml b/Cargo.toml index 214fa1fe1..495caf998 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,12 @@ targets = [ [features] default = ["std"] + +# This enables use of std. Disabling this enables no_std, and +# requires nightly Rust. std = ["io-lifetimes"] + +# This is used in the port of std to rustix. rustc-dep-of-std = [ "core", "alloc", diff --git a/benches/mod.rs b/benches/mod.rs index b87287e04..01c9898ac 100644 --- a/benches/mod.rs +++ b/benches/mod.rs @@ -62,7 +62,7 @@ mod suite { assert_eq!( libc::fstatat( libc::AT_FDCWD, - rustix::zstr!("/").as_ptr() as _, + rustix::cstr!("/").as_ptr() as _, s.as_mut_ptr(), 0 ), @@ -78,7 +78,7 @@ mod suite { c.bench_function("simple statat cstr", |b| { b.iter(|| { - statat(cwd(), rustix::zstr!("/"), AtFlags::empty()).unwrap(); + statat(cwd(), rustix::cstr!("/"), AtFlags::empty()).unwrap(); }) }); } diff --git a/build.rs b/build.rs index 57afad75b..11fffefe0 100644 --- a/build.rs +++ b/build.rs @@ -16,11 +16,9 @@ fn main() { // Features only used in no-std configurations. #[cfg(not(feature = "std"))] { - use_feature_or_nothing("vec_into_raw_parts"); - use_feature_or_nothing("toowned_clone_into"); - use_feature_or_nothing("specialization"); - use_feature_or_nothing("slice_internals"); use_feature_or_nothing("const_raw_ptr_deref"); + use_feature_or_nothing("core_c_str"); + use_feature_or_nothing("alloc_c_string"); } // Gather target information. diff --git a/src/zstr.rs b/src/cstr.rs similarity index 68% rename from src/zstr.rs rename to src/cstr.rs index d20ec9768..5e3364380 100644 --- a/src/zstr.rs +++ b/src/cstr.rs @@ -1,21 +1,21 @@ -/// A macro for [`ZStr`] literals. +/// A macro for [`CStr`] literals. /// /// This can make passing string literals to rustix APIs more efficient, since /// most underlying system calls with string arguments expect NUL-terminated -/// strings, and passing strings to rustix as `ZStr`s means that rustix doesn't +/// strings, and passing strings to rustix as `CStr`s means that rustix doesn't /// need to copy them into a separate buffer to NUL-terminate them. /// -/// [`ZStr`]: crate::ffi::ZStr +/// [`CStr`]: crate::ffi::CStr /// /// # Examples /// /// ```rust,no_run /// # #[cfg(feature = "fs")] /// # fn main() -> rustix::io::Result<()> { +/// use rustix::cstr; /// use rustix::fs::{cwd, statat, AtFlags}; -/// use rustix::zstr; /// -/// let metadata = statat(cwd(), zstr!("test.txt"), AtFlags::empty())?; +/// let metadata = statat(cwd(), cstr!("test.txt"), AtFlags::empty())?; /// # Ok(()) /// # } /// # #[cfg(not(feature = "fs"))] @@ -23,7 +23,7 @@ /// ``` #[allow(unused_macros)] #[macro_export] -macro_rules! zstr { +macro_rules! cstr { ($str:literal) => {{ // Check for NUL manually, to ensure safety. // @@ -35,7 +35,7 @@ macro_rules! zstr { // constant-fold away. assert!( !$str.bytes().any(|b| b == b'\0'), - "zstr argument contains embedded NUL bytes", + "cstr argument contains embedded NUL bytes", ); #[allow(unsafe_code, unused_unsafe)] @@ -47,30 +47,30 @@ macro_rules! zstr { // Safety: We have manually checked that the string does not contain // embedded NULs above, and we append or own NUL terminator here. unsafe { - $crate::ffi::ZStr::from_bytes_with_nul_unchecked(concat!($str, "\0").as_bytes()) + $crate::ffi::CStr::from_bytes_with_nul_unchecked(concat!($str, "\0").as_bytes()) } } }}; } #[test] -fn test_zstr() { - use crate::ffi::ZString; +fn test_cstr() { + use crate::ffi::CString; use alloc::borrow::ToOwned; - assert_eq!(zstr!(""), &*ZString::new("").unwrap()); - assert_eq!(zstr!("").to_owned(), ZString::new("").unwrap()); - assert_eq!(zstr!("hello"), &*ZString::new("hello").unwrap()); - assert_eq!(zstr!("hello").to_owned(), ZString::new("hello").unwrap()); + assert_eq!(cstr!(""), &*CString::new("").unwrap()); + assert_eq!(cstr!("").to_owned(), CString::new("").unwrap()); + assert_eq!(cstr!("hello"), &*CString::new("hello").unwrap()); + assert_eq!(cstr!("hello").to_owned(), CString::new("hello").unwrap()); } #[test] #[should_panic] -fn test_invalid_zstr() { - let _ = zstr!("hello\0world"); +fn test_invalid_cstr() { + let _ = cstr!("hello\0world"); } #[test] #[should_panic] -fn test_invalid_empty_zstr() { - let _ = zstr!("\0"); +fn test_invalid_empty_cstr() { + let _ = cstr!("\0"); } diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index bf552547a..a1af4e818 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -1,24 +1,9 @@ //! Utilities related to FFI bindings. -/// Minimal and unoptimized `strlen` implementation. -/// -/// TODO: Optimize this by reading a `usize` at a time. #[cfg(not(feature = "std"))] -#[allow(unsafe_code)] -unsafe fn strlen(mut s: *const u8) -> usize { - let mut len = 0; - while *s != b'\0' { - len += 1; - s = s.add(1); - } - len -} - -#[cfg(not(feature = "std"))] -mod z_str; - +pub use alloc::ffi::{CString, NulError}; #[cfg(not(feature = "std"))] -pub use z_str::{FromBytesWithNulError, FromVecWithNulError, NulError, ZStr, ZString}; +pub use core::ffi::{CStr, FromBytesWithNulError}; #[cfg(feature = "std")] -pub use std::ffi::{CStr as ZStr, CString as ZString, FromBytesWithNulError, NulError}; +pub use std::ffi::{CStr, CString, FromBytesWithNulError, NulError}; diff --git a/src/ffi/z_str.rs b/src/ffi/z_str.rs deleted file mode 100644 index b99701f83..000000000 --- a/src/ffi/z_str.rs +++ /dev/null @@ -1,1748 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/ffi/c_str.rs at revision -//! dca3f1b786efd27be3b325ed1e01e247aa589c3b. -//! -//! ZStrings are like std's CStrings except that they use `u8` instead of -//! `c_char`, so that they're not platform-dependent. - -#![allow(unsafe_code)] -#![deny(unsafe_op_in_unsafe_fn)] - -use super::strlen; -use crate::io; -use alloc::borrow::{Cow, ToOwned}; -use alloc::boxed::Box; -use alloc::rc::Rc; -use alloc::string::String; -use alloc::sync::Arc; -use alloc::vec::Vec; -use core::ascii; -use core::borrow::Borrow; -use core::cmp::Ordering; -use core::fmt::{self, Write}; -use core::mem; -#[cfg(vec_into_raw_parts)] -use core::num::NonZeroU8; -use core::ops; -use core::ptr; -use core::slice; -#[cfg(slice_internals)] -use core::slice::memchr::memchr; -use core::str::{self, Utf8Error}; - -#[cfg(not(slice_internals))] -fn memchr(x: u8, text: &[u8]) -> Option { - text.iter().position(|elt| *elt == x) -} - -/// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the -/// middle. -/// -/// This type serves the purpose of being able to safely generate a -/// C-compatible string from a Rust byte slice or vector. An instance of this -/// type is a static guarantee that the underlying bytes contain no interior 0 -/// bytes ("nul characters") and that the final byte is 0 ("nul terminator"). -/// -/// `ZString` is to &[ZStr] as [`String`] is to &[str]: the former -/// in each pair are owned strings; the latter are borrowed -/// references. -/// -/// # Creating a `ZString` -/// -/// A `ZString` is created from either a byte slice or a byte vector, -/// or anything that implements [Into]<[Vec]<[u8]>> (for -/// example, you can build a `ZString` straight out of a [`String`] or -/// a &[str], since both implement that trait). -/// -/// The [`ZString::new`] method will actually check that the provided &[[u8]] -/// does not have 0 bytes in the middle, and return an error if it -/// finds one. -/// -/// # Extracting a raw pointer to the whole C string -/// -/// `ZString` implements an [`as_ptr`][`ZStr::as_ptr`] method through the [`Deref`] -/// trait. This method will give you a `*const u8` which you can -/// feed directly to extern functions that expect a nul-terminated -/// string, like C's `strdup()`. Notice that [`as_ptr`][`ZStr::as_ptr`] returns a -/// read-only pointer; if the C code writes to it, that causes -/// undefined behavior. -/// -/// # Extracting a slice of the whole C string -/// -/// Alternatively, you can obtain a &[[u8]] slice from a -/// `ZString` with the [`ZString::as_bytes`] method. Slices produced in this -/// way do *not* contain the trailing nul terminator. This is useful -/// when you will be calling an extern function that takes a `*const -/// u8` argument which is not necessarily nul-terminated, plus another -/// argument with the length of the string — like C's `strndup()`. -/// You can of course get the slice's length with its -/// [`len`][slice::len] method. -/// -/// If you need a &[[u8]] slice *with* the nul terminator, you -/// can use [`ZString::as_bytes_with_nul`] instead. -/// -/// Once you have the kind of slice you need (with or without a nul -/// terminator), you can call the slice's own -/// [`as_ptr`][slice::as_ptr] method to get a read-only raw pointer to pass to -/// extern functions. See the documentation for that function for a -/// discussion on ensuring the lifetime of the raw pointer. -/// -/// [str]: prim@str "str" -/// [`Deref`]: ops::Deref -/// -/// # Examples -/// -/// ```ignore (extern-declaration) -/// # fn main() { -/// use std::ffi::ZString; -/// -/// extern "C" { -/// fn my_printer(s: *const u8); -/// } -/// -/// // We are certain that our string doesn't have 0 bytes in the middle, -/// // so we can .expect() -/// let c_to_print = ZString::new("Hello, world!").expect("ZString::new failed"); -/// unsafe { -/// my_printer(c_to_print.as_ptr()); -/// } -/// # } -/// ``` -/// -/// # Safety -/// -/// `ZString` is intended for working with traditional C-style strings -/// (a sequence of non-nul bytes terminated by a single nul byte); the -/// primary use case for these kinds of strings is interoperating with C-like -/// code. Often you will need to transfer ownership to/from that external -/// code. It is strongly recommended that you thoroughly read through the -/// documentation of `ZString` before use, as improper ownership management -/// of `ZString` instances can lead to invalid memory accesses, memory leaks, -/// and other memory errors. -#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)] -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -pub struct ZString { - // Invariant 1: the slice ends with a zero byte and has a length of at least one. - // Invariant 2: the slice contains only one zero byte. - // Improper usage of unsafe function can break Invariant 2, but not Invariant 1. - inner: Box<[u8]>, -} - -/// Representation of a borrowed C string. -/// -/// This type represents a borrowed reference to a nul-terminated -/// array of bytes. It can be constructed safely from a &[[u8]] -/// slice, or unsafely from a raw `*const u8`. It can then be -/// converted to a Rust &[str] by performing UTF-8 validation, or -/// into an owned [`ZString`]. -/// -/// `&ZStr` is to [`ZString`] as &[str] is to [`String`]: the former -/// in each pair are borrowed references; the latter are owned -/// strings. -/// -/// Note that this structure is **not** `repr(C)` and is not recommended to be -/// placed in the signatures of FFI functions. Instead, safe wrappers of FFI -/// functions may leverage the unsafe [`ZStr::from_ptr`] constructor to provide -/// a safe interface to other consumers. -/// -/// # Examples -/// -/// Inspecting a foreign C string: -/// -/// ```ignore (extern-declaration) -/// use std::ffi::ZStr; -/// -/// extern "C" { fn my_string() -> *const u8; } -/// -/// unsafe { -/// let slice = ZStr::from_ptr(my_string()); -/// println!("string buffer size without nul terminator: {}", slice.to_bytes().len()); -/// } -/// ``` -/// -/// Passing a Rust-originating C string: -/// -/// ```ignore (extern-declaration) -/// use std::ffi::{ZString, ZStr}; -/// -/// fn work(data: &ZStr) { -/// extern "C" { fn work_with(data: *const u8); } -/// -/// unsafe { work_with(data.as_ptr()) } -/// } -/// -/// let s = ZString::new("data data data data").expect("ZString::new failed"); -/// work(&s); -/// ``` -/// -/// Converting a foreign C string into a Rust [`String`]: -/// -/// ```ignore (extern-declaration) -/// use std::ffi::ZStr; -/// -/// extern "C" { fn my_string() -> *const u8; } -/// -/// fn my_string_safe() -> String { -/// unsafe { -/// ZStr::from_ptr(my_string()).to_string_lossy().into_owned() -/// } -/// } -/// -/// println!("string: {}", my_string_safe()); -/// ``` -/// -/// [str]: prim@str "str" -#[derive(Hash)] -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -// FIXME: -// `fn from` in `impl From<&ZStr> for Box` current implementation relies -// on `ZStr` being layout-compatible with `[u8]`. -// When attribute privacy is implemented, `ZStr` should be annotated as `#[repr(transparent)]`. -// Anyway, `ZStr` representation and layout are considered implementation detail, are -// not documented and must not be relied upon. -pub struct ZStr { - // FIXME: this should not be represented with a DST slice but rather with - // just a raw `u8` along with some form of marker to make - // this an unsized type. Essentially `sizeof(&ZStr)` should be the - // same as `sizeof(&u8)` but `ZStr` should be an unsized type. - inner: [u8], -} - -/// An error indicating that an interior nul byte was found. -/// -/// While Rust strings may contain nul bytes in the middle, C strings -/// can't, as that byte would effectively truncate the string. -/// -/// This error is created by the [`new`][`ZString::new`] method on -/// [`ZString`]. See its documentation for more. -/// -/// # Examples -/// -/// ``` -/// use std::ffi::{ZString, NulError}; -/// -/// let _: NulError = ZString::new(b"f\0oo".to_vec()).unwrap_err(); -/// ``` -#[derive(Clone, PartialEq, Eq, Debug)] -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -pub struct NulError(usize, Vec); - -/// An error indicating that a nul byte was not in the expected position. -/// -/// The slice used to create a [`ZStr`] must have one and only one nul byte, -/// positioned at the end. -/// -/// This error is created by the [`ZStr::from_bytes_with_nul`] method. -/// See its documentation for more. -/// -/// # Examples -/// -/// ``` -/// use std::ffi::{ZStr, FromBytesWithNulError}; -/// -/// let _: FromBytesWithNulError = ZStr::from_bytes_with_nul(b"f\0oo").unwrap_err(); -/// ``` -#[derive(Clone, PartialEq, Eq, Debug)] -#[cfg_attr(staged_api, stable(feature = "cstr_from_bytes", since = "1.10.0"))] -pub struct FromBytesWithNulError { - kind: FromBytesWithNulErrorKind, -} - -/// An error indicating that a nul byte was not in the expected position. -/// -/// The vector used to create a [`ZString`] must have one and only one nul byte, -/// positioned at the end. -/// -/// This error is created by the [`ZString::from_vec_with_nul`] method. -/// See its documentation for more. -/// -/// # Examples -/// -/// ``` -/// use std::ffi::{ZString, FromVecWithNulError}; -/// -/// let _: FromVecWithNulError = ZString::from_vec_with_nul(b"f\0oo".to_vec()).unwrap_err(); -/// ``` -#[derive(Clone, PartialEq, Eq, Debug)] -#[cfg_attr( - staged_api, - stable(feature = "cstring_from_vec_with_nul", since = "1.58.0") -)] -pub struct FromVecWithNulError { - error_kind: FromBytesWithNulErrorKind, - bytes: Vec, -} - -#[derive(Clone, PartialEq, Eq, Debug)] -enum FromBytesWithNulErrorKind { - InteriorNul(usize), - NotNulTerminated, -} - -impl FromBytesWithNulError { - fn interior_nul(pos: usize) -> FromBytesWithNulError { - FromBytesWithNulError { - kind: FromBytesWithNulErrorKind::InteriorNul(pos), - } - } - fn not_nul_terminated() -> FromBytesWithNulError { - FromBytesWithNulError { - kind: FromBytesWithNulErrorKind::NotNulTerminated, - } - } -} - -#[cfg_attr( - staged_api, - stable(feature = "cstring_from_vec_with_nul", since = "1.58.0") -)] -impl FromVecWithNulError { - /// Returns a slice of [`u8`]s bytes that were attempted to convert to a [`ZString`]. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::ffi::ZString; - /// - /// // Some invalid bytes in a vector - /// let bytes = b"f\0oo".to_vec(); - /// - /// let value = ZString::from_vec_with_nul(bytes.clone()); - /// - /// assert_eq!(&bytes[..], value.unwrap_err().as_bytes()); - /// ``` - #[must_use] - #[cfg_attr( - staged_api, - stable(feature = "cstring_from_vec_with_nul", since = "1.58.0") - )] - pub fn as_bytes(&self) -> &[u8] { - &self.bytes[..] - } - - /// Returns the bytes that were attempted to convert to a [`ZString`]. - /// - /// This method is carefully constructed to avoid allocation. It will - /// consume the error, moving out the bytes, so that a copy of the bytes - /// does not need to be made. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::ffi::ZString; - /// - /// // Some invalid bytes in a vector - /// let bytes = b"f\0oo".to_vec(); - /// - /// let value = ZString::from_vec_with_nul(bytes.clone()); - /// - /// assert_eq!(bytes, value.unwrap_err().into_bytes()); - /// ``` - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr( - staged_api, - stable(feature = "cstring_from_vec_with_nul", since = "1.58.0") - )] - pub fn into_bytes(self) -> Vec { - self.bytes - } -} - -/// An error indicating invalid UTF-8 when converting a [`ZString`] into a [`String`]. -/// -/// `ZString` is just a wrapper over a buffer of bytes with a nul terminator; -/// [`ZString::into_string`] performs UTF-8 validation on those bytes and may -/// return this error. -/// -/// This `struct` is created by [`ZString::into_string()`]. See -/// its documentation for more. -#[derive(Clone, PartialEq, Eq, Debug)] -#[cfg_attr(staged_api, stable(feature = "cstring_into", since = "1.7.0"))] -pub struct IntoStringError { - inner: ZString, - error: Utf8Error, -} - -impl ZString { - /// Creates a new C-compatible string from a container of bytes. - /// - /// This function will consume the provided data and use the - /// underlying bytes to construct a new string, ensuring that - /// there is a trailing 0 byte. This trailing 0 byte will be - /// appended by this function; the provided data should *not* - /// contain any 0 bytes in it. - /// - /// # Examples - /// - /// ```ignore (extern-declaration) - /// use std::ffi::ZString; - /// - /// extern "C" { fn puts(s: *const u8); } - /// - /// let to_print = ZString::new("Hello!").expect("ZString::new failed"); - /// unsafe { - /// puts(to_print.as_ptr()); - /// } - /// ``` - /// - /// # Errors - /// - /// This function will return an error if the supplied bytes contain an - /// internal 0 byte. The [`NulError`] returned will contain the bytes as well as - /// the position of the nul byte. - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - pub fn new>>(t: T) -> Result { - trait SpecIntoVec { - fn into_vec(self) -> Vec; - } - #[cfg(not(specialization))] - impl>> SpecIntoVec for T { - fn into_vec(self) -> Vec { - self.into() - } - } - #[cfg(specialization)] - impl>> SpecIntoVec for T { - default fn into_vec(self) -> Vec { - self.into() - } - } - // Specialization for avoiding reallocation. - #[cfg(specialization)] - impl SpecIntoVec for &'_ [u8] { - fn into_vec(self) -> Vec { - let mut v = Vec::with_capacity(self.len() + 1); - v.extend(self); - v - } - } - #[cfg(specialization)] - impl SpecIntoVec for &'_ str { - fn into_vec(self) -> Vec { - let mut v = Vec::with_capacity(self.len() + 1); - v.extend(self.as_bytes()); - v - } - } - - Self::_new(SpecIntoVec::into_vec(t)) - } - - fn _new(bytes: Vec) -> Result { - match memchr(b'\0', &bytes) { - Some(i) => Err(NulError(i, bytes)), - None => Ok(unsafe { ZString::from_vec_unchecked(bytes) }), - } - } - - /// Creates a C-compatible string by consuming a byte vector, - /// without checking for interior 0 bytes. - /// - /// Trailing 0 byte will be appended by this function. - /// - /// This method is equivalent to [`ZString::new`] except that no runtime - /// assertion is made that `v` contains no 0 bytes, and it requires an - /// actual byte vector, not anything that can be converted to one with Into. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZString; - /// - /// let raw = b"foo".to_vec(); - /// unsafe { - /// let c_string = ZString::from_vec_unchecked(raw); - /// } - /// ``` - #[must_use] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - pub unsafe fn from_vec_unchecked(mut v: Vec) -> ZString { - v.reserve_exact(1); - v.push(b'\0'); - ZString { - inner: v.into_boxed_slice(), - } - } - - /// Retakes ownership of a `ZString` that was transferred to C via - /// [`ZString::into_raw`]. - /// - /// Additionally, the length of the string will be recalculated from the pointer. - /// - /// # Safety - /// - /// This should only ever be called with a pointer that was earlier - /// obtained by calling [`ZString::into_raw`]. Other usage (e.g., trying to take - /// ownership of a string that was allocated by foreign code) is likely to lead - /// to undefined behavior or allocator corruption. - /// - /// It should be noted that the length isn't just "recomputed," but that - /// the recomputed length must match the original length from the - /// [`ZString::into_raw`] call. This means the [`ZString::into_raw`]/`from_raw` - /// methods should not be used when passing the string to C functions that can - /// modify the string's length. - /// - /// > **Note:** If you need to borrow a string that was allocated by - /// > foreign code, use [`ZStr`]. If you need to take ownership of - /// > a string that was allocated by foreign code, you will need to - /// > make your own provisions for freeing it appropriately, likely - /// > with the foreign code's API to do that. - /// - /// # Examples - /// - /// Creates a `ZString`, pass ownership to an `extern` function (via raw pointer), then retake - /// ownership with `from_raw`: - /// - /// ```ignore (extern-declaration) - /// use std::ffi::ZString; - /// - /// extern "C" { - /// fn some_extern_function(s: *mut u8); - /// } - /// - /// let c_string = ZString::new("Hello!").expect("ZString::new failed"); - /// let raw = c_string.into_raw(); - /// unsafe { - /// some_extern_function(raw); - /// let c_string = ZString::from_raw(raw); - /// } - /// ``` - #[must_use = "call `drop(from_raw(ptr))` if you intend to drop the `ZString`"] - #[cfg_attr(staged_api, stable(feature = "cstr_memory", since = "1.4.0"))] - pub unsafe fn from_raw(ptr: *mut u8) -> ZString { - // SAFETY: This is called with a pointer that was obtained from a call - // to `ZString::into_raw` and the length has not been modified. As such, - // we know there is a NUL byte (and only one) at the end and that the - // information about the size of the allocation is correct on Rust's - // side. - unsafe { - let len = strlen(ptr) + 1; // Including the NUL byte - let slice = slice::from_raw_parts_mut(ptr, len as usize); - ZString { - inner: Box::from_raw(slice as *mut [u8]), - } - } - } - - /// Consumes the `ZString` and transfers ownership of the string to a C caller. - /// - /// The pointer which this function returns must be returned to Rust and reconstituted using - /// [`ZString::from_raw`] to be properly deallocated. Specifically, one - /// should *not* use the standard C `free()` function to deallocate - /// this string. - /// - /// Failure to call [`ZString::from_raw`] will lead to a memory leak. - /// - /// The C side must **not** modify the length of the string (by writing a - /// `null` somewhere inside the string or removing the final one) before - /// it makes it back into Rust using [`ZString::from_raw`]. See the safety section - /// in [`ZString::from_raw`]. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZString; - /// - /// let c_string = ZString::new("foo").expect("ZString::new failed"); - /// - /// let ptr = c_string.into_raw(); - /// - /// unsafe { - /// assert_eq!(b'f', *ptr as u8); - /// assert_eq!(b'o', *ptr.offset(1) as u8); - /// assert_eq!(b'o', *ptr.offset(2) as u8); - /// assert_eq!(b'\0', *ptr.offset(3) as u8); - /// - /// // retake pointer to free memory - /// let _ = ZString::from_raw(ptr); - /// } - /// ``` - #[inline] - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr(staged_api, stable(feature = "cstr_memory", since = "1.4.0"))] - pub fn into_raw(self) -> *mut u8 { - Box::into_raw(self.into_inner()) as *mut u8 - } - - /// Converts the `ZString` into a [`String`] if it contains valid UTF-8 data. - /// - /// On failure, ownership of the original `ZString` is returned. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZString; - /// - /// let valid_utf8 = vec![b'f', b'o', b'o']; - /// let cstring = ZString::new(valid_utf8).expect("ZString::new failed"); - /// assert_eq!(cstring.into_string().expect("into_string() call failed"), "foo"); - /// - /// let invalid_utf8 = vec![b'f', 0xff, b'o', b'o']; - /// let cstring = ZString::new(invalid_utf8).expect("ZString::new failed"); - /// let err = cstring.into_string().err().expect("into_string().err() failed"); - /// assert_eq!(err.utf8_error().valid_up_to(), 1); - /// ``` - #[cfg_attr(staged_api, stable(feature = "cstring_into", since = "1.7.0"))] - pub fn into_string(self) -> Result { - String::from_utf8(self.into_bytes()).map_err(|e| IntoStringError { - error: e.utf8_error(), - inner: unsafe { ZString::from_vec_unchecked(e.into_bytes()) }, - }) - } - - /// Consumes the `ZString` and returns the underlying byte buffer. - /// - /// The returned buffer does **not** contain the trailing nul - /// terminator, and it is guaranteed to not have any interior nul - /// bytes. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZString; - /// - /// let c_string = ZString::new("foo").expect("ZString::new failed"); - /// let bytes = c_string.into_bytes(); - /// assert_eq!(bytes, vec![b'f', b'o', b'o']); - /// ``` - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr(staged_api, stable(feature = "cstring_into", since = "1.7.0"))] - pub fn into_bytes(self) -> Vec { - let mut vec = self.into_inner().into_vec(); - let _nul = vec.pop(); - debug_assert_eq!(_nul, Some(0u8)); - vec - } - - /// Equivalent to [`ZString::into_bytes()`] except that the - /// returned vector includes the trailing nul terminator. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZString; - /// - /// let c_string = ZString::new("foo").expect("ZString::new failed"); - /// let bytes = c_string.into_bytes_with_nul(); - /// assert_eq!(bytes, vec![b'f', b'o', b'o', b'\0']); - /// ``` - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr(staged_api, stable(feature = "cstring_into", since = "1.7.0"))] - pub fn into_bytes_with_nul(self) -> Vec { - self.into_inner().into_vec() - } - - /// Returns the contents of this `ZString` as a slice of bytes. - /// - /// The returned slice does **not** contain the trailing nul - /// terminator, and it is guaranteed to not have any interior nul - /// bytes. If you need the nul terminator, use - /// [`ZString::as_bytes_with_nul`] instead. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZString; - /// - /// let c_string = ZString::new("foo").expect("ZString::new failed"); - /// let bytes = c_string.as_bytes(); - /// assert_eq!(bytes, &[b'f', b'o', b'o']); - /// ``` - #[inline] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - pub fn as_bytes(&self) -> &[u8] { - // SAFETY: ZString has a length at least 1 - unsafe { self.inner.get_unchecked(..self.inner.len() - 1) } - } - - /// Equivalent to [`ZString::as_bytes()`] except that the - /// returned slice includes the trailing nul terminator. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZString; - /// - /// let c_string = ZString::new("foo").expect("ZString::new failed"); - /// let bytes = c_string.as_bytes_with_nul(); - /// assert_eq!(bytes, &[b'f', b'o', b'o', b'\0']); - /// ``` - #[inline] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - pub fn as_bytes_with_nul(&self) -> &[u8] { - &self.inner - } - - /// Extracts a [`ZStr`] slice containing the entire string. - /// - /// # Examples - /// - /// ``` - /// use rustix::ffi::{ZString, ZStr}; - /// - /// let z_string = ZString::new(b"foo".to_vec()).expect("ZString::new failed"); - /// let zstr = z_string.as_z_str(); - /// assert_eq!(zstr, - /// ZStr::from_bytes_with_nul(b"foo\0").expect("ZStr::from_bytes_with_nul failed")); - /// ``` - #[inline] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "as_c_str", since = "1.20.0"))] - pub fn as_z_str(&self) -> &ZStr { - &*self - } - - /// Extracts a [`CStr`] slice containing the entire string. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::CStr; - /// use rustix::ffi::{ZString, ZStr}; - /// - /// let z_string = ZString::new(b"foo".to_vec()).expect("ZString::new failed"); - /// let cstr = z_string.as_c_str(); - /// assert_eq!(cstr, - /// CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed")); - /// ``` - #[cfg(not(feature = "rustc-dep-of-std"))] - #[inline] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "as_c_str", since = "1.20.0"))] - pub fn as_c_str(&self) -> &ZStr { - self.as_z_str() - } - - /// Converts this `ZString` into a boxed [`ZStr`]. - /// - /// # Examples - /// - /// ``` - /// use rustix::ffi::{ZString, ZStr}; - /// - /// let z_string = ZString::new(b"foo".to_vec()).expect("ZString::new failed"); - /// let boxed = c_string.into_boxed_z_str(); - /// assert_eq!(&*boxed, - /// ZStr::from_bytes_with_nul(b"foo\0").expect("ZStr::from_bytes_with_nul failed")); - /// ``` - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr(staged_api, stable(feature = "into_boxed_c_str", since = "1.20.0"))] - pub fn into_boxed_z_str(self) -> Box { - unsafe { Box::from_raw(Box::into_raw(self.into_inner()) as *mut ZStr) } - } - - /// Converts this `ZString` into a boxed [`CStr`]. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZStr; - /// use rustix::ffi::{ZString, ZStr}; - /// - /// let z_string = ZString::new(b"foo".to_vec()).expect("ZString::new failed"); - /// let boxed = z_string.into_boxed_c_str(); - /// assert_eq!(&*boxed, - /// CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed")); - /// ``` - #[cfg(feature = "std")] - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr(staged_api, stable(feature = "into_boxed_c_str", since = "1.20.0"))] - pub fn into_boxed_c_str(self) -> Box { - self.into_boxed_z_str() - } - - /// Bypass "move out of struct which implements [`Drop`] trait" restriction. - #[inline] - fn into_inner(self) -> Box<[u8]> { - // Rationale: `mem::forget(self)` invalidates the previous call to `ptr::read(&self.inner)` - // so we use `ManuallyDrop` to ensure `self` is not dropped. - // Then we can return the box directly without invalidating it. - // See https://github.com/rust-lang/rust/issues/62553. - let this = mem::ManuallyDrop::new(self); - unsafe { ptr::read(&this.inner) } - } - - /// Converts a [Vec]<[u8]> to a [`ZString`] without checking the - /// invariants on the given [`Vec`]. - /// - /// # Safety - /// - /// The given [`Vec`] **must** have one nul byte as its last element. - /// This means it cannot be empty nor have any other nul byte anywhere else. - /// - /// # Example - /// - /// ``` - /// use std::ffi::ZString; - /// assert_eq!( - /// unsafe { ZString::from_vec_with_nul_unchecked(b"abc\0".to_vec()) }, - /// unsafe { ZString::from_vec_unchecked(b"abc".to_vec()) } - /// ); - /// ``` - #[must_use] - #[cfg_attr( - staged_api, - stable(feature = "cstring_from_vec_with_nul", since = "1.58.0") - )] - pub unsafe fn from_vec_with_nul_unchecked(v: Vec) -> Self { - Self { - inner: v.into_boxed_slice(), - } - } - - /// Attempts to converts a [Vec]<[u8]> to a [`ZString`]. - /// - /// Runtime checks are present to ensure there is only one nul byte in the - /// [`Vec`], its last element. - /// - /// # Errors - /// - /// If a nul byte is present and not the last element or no nul bytes - /// is present, an error will be returned. - /// - /// # Examples - /// - /// A successful conversion will produce the same result as [`ZString::new`] - /// when called without the ending nul byte. - /// - /// ``` - /// use std::ffi::ZString; - /// assert_eq!( - /// ZString::from_vec_with_nul(b"abc\0".to_vec()) - /// .expect("ZString::from_vec_with_nul failed"), - /// ZString::new(b"abc".to_vec()).expect("ZString::new failed") - /// ); - /// ``` - /// - /// An incorrectly formatted [`Vec`] will produce an error. - /// - /// ``` - /// use std::ffi::{ZString, FromVecWithNulError}; - /// // Interior nul byte - /// let _: FromVecWithNulError = ZString::from_vec_with_nul(b"a\0bc".to_vec()).unwrap_err(); - /// // No nul byte - /// let _: FromVecWithNulError = ZString::from_vec_with_nul(b"abc".to_vec()).unwrap_err(); - /// ``` - #[cfg_attr( - staged_api, - stable(feature = "cstring_from_vec_with_nul", since = "1.58.0") - )] - pub fn from_vec_with_nul(v: Vec) -> Result { - let nul_pos = memchr(b'\0', &v); - match nul_pos { - Some(nul_pos) if nul_pos + 1 == v.len() => { - // SAFETY: We know there is only one nul byte, at the end - // of the vec. - Ok(unsafe { Self::from_vec_with_nul_unchecked(v) }) - } - Some(nul_pos) => Err(FromVecWithNulError { - error_kind: FromBytesWithNulErrorKind::InteriorNul(nul_pos), - bytes: v, - }), - None => Err(FromVecWithNulError { - error_kind: FromBytesWithNulErrorKind::NotNulTerminated, - bytes: v, - }), - } - } -} - -// Turns this `ZString` into an empty string to prevent -// memory-unsafe code from working by accident. Inline -// to prevent LLVM from optimizing it away in debug builds. -#[cfg_attr(staged_api, stable(feature = "cstring_drop", since = "1.13.0"))] -impl Drop for ZString { - #[inline] - fn drop(&mut self) { - unsafe { - *self.inner.get_unchecked_mut(0) = 0; - } - } -} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl ops::Deref for ZString { - type Target = ZStr; - - #[inline] - fn deref(&self) -> &ZStr { - unsafe { ZStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) } - } -} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl fmt::Debug for ZString { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -#[cfg_attr(staged_api, stable(feature = "cstring_into", since = "1.7.0"))] -impl From for Vec { - /// Converts a [`ZString`] into a [Vec]<[u8]>. - /// - /// The conversion consumes the [`ZString`], and removes the terminating NUL byte. - #[inline] - fn from(s: ZString) -> Vec { - s.into_bytes() - } -} - -#[cfg_attr(staged_api, stable(feature = "cstr_debug", since = "1.3.0"))] -impl fmt::Debug for ZStr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "\"")?; - for byte in self - .to_bytes() - .iter() - .flat_map(|&b| ascii::escape_default(b)) - { - f.write_char(byte as char)?; - } - write!(f, "\"") - } -} - -#[cfg_attr(staged_api, stable(feature = "cstr_default", since = "1.10.0"))] -impl Default for &ZStr { - fn default() -> Self { - const SLICE: &[u8] = &[0]; - unsafe { ZStr::from_ptr(SLICE.as_ptr()) } - } -} - -#[cfg_attr(staged_api, stable(feature = "cstr_default", since = "1.10.0"))] -impl Default for ZString { - /// Creates an empty `ZString`. - fn default() -> ZString { - let a: &ZStr = Default::default(); - a.to_owned() - } -} - -#[cfg_attr(staged_api, stable(feature = "cstr_borrow", since = "1.3.0"))] -impl Borrow for ZString { - #[inline] - fn borrow(&self) -> &ZStr { - self - } -} - -#[cfg_attr( - staged_api, - stable(feature = "cstring_from_cow_cstr", since = "1.28.0") -)] -impl<'a> From> for ZString { - #[inline] - fn from(s: Cow<'a, ZStr>) -> Self { - s.into_owned() - } -} - -#[cfg_attr(staged_api, stable(feature = "box_from_c_str", since = "1.17.0"))] -impl From<&ZStr> for Box { - fn from(s: &ZStr) -> Box { - let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul()); - unsafe { Box::from_raw(Box::into_raw(boxed) as *mut ZStr) } - } -} - -#[cfg_attr(staged_api, stable(feature = "box_from_cow", since = "1.45.0"))] -impl From> for Box { - #[inline] - fn from(cow: Cow<'_, ZStr>) -> Box { - match cow { - Cow::Borrowed(s) => Box::from(s), - Cow::Owned(s) => Box::from(s), - } - } -} - -#[cfg_attr(staged_api, stable(feature = "c_string_from_box", since = "1.18.0"))] -impl From> for ZString { - /// Converts a [Box]<[ZStr]> into a [`ZString`] without copying or allocating. - #[inline] - fn from(s: Box) -> ZString { - s.into_z_string() - } -} - -#[cfg(vec_into_raw_parts)] -#[cfg_attr( - staged_api, - stable(feature = "cstring_from_vec_of_nonzerou8", since = "1.43.0") -)] -impl From> for ZString { - /// Converts a [Vec]<[NonZeroU8]> into a [`ZString`] without - /// copying nor checking for inner null bytes. - #[inline] - fn from(v: Vec) -> ZString { - 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`. - ZString::from_vec_unchecked(v) - } - } -} - -#[cfg_attr(staged_api, stable(feature = "more_box_slice_clone", since = "1.29.0"))] -impl Clone for Box { - #[inline] - fn clone(&self) -> Self { - (**self).into() - } -} - -#[cfg_attr(staged_api, stable(feature = "box_from_c_string", since = "1.20.0"))] -impl From for Box { - /// Converts a [`ZString`] into a [Box]<[ZStr]> without copying or allocating. - #[inline] - fn from(s: ZString) -> Box { - s.into_boxed_z_str() - } -} - -#[cfg_attr(staged_api, stable(feature = "cow_from_cstr", since = "1.28.0"))] -impl<'a> From for Cow<'a, ZStr> { - /// Converts a [`ZString`] into an owned [`Cow`] without copying or allocating. - #[inline] - fn from(s: ZString) -> Cow<'a, ZStr> { - Cow::Owned(s) - } -} - -#[cfg_attr(staged_api, stable(feature = "cow_from_cstr", since = "1.28.0"))] -impl<'a> From<&'a ZStr> for Cow<'a, ZStr> { - /// Converts a [`ZStr`] into a borrowed [`Cow`] without copying or allocating. - #[inline] - fn from(s: &'a ZStr) -> Cow<'a, ZStr> { - Cow::Borrowed(s) - } -} - -#[cfg_attr(staged_api, stable(feature = "cow_from_cstr", since = "1.28.0"))] -impl<'a> From<&'a ZString> for Cow<'a, ZStr> { - /// Converts a `&`[`ZString`] into a borrowed [`Cow`] without copying or allocating. - #[inline] - fn from(s: &'a ZString) -> Cow<'a, ZStr> { - Cow::Borrowed(s.as_z_str()) - } -} - -#[cfg_attr(staged_api, stable(feature = "shared_from_slice2", since = "1.24.0"))] -impl From for Arc { - /// Converts a [`ZString`] into an [Arc]<[ZStr]> without copying or allocating. - #[inline] - fn from(s: ZString) -> Arc { - let arc: Arc<[u8]> = Arc::from(s.into_inner()); - unsafe { Arc::from_raw(Arc::into_raw(arc) as *const ZStr) } - } -} - -#[cfg_attr(staged_api, stable(feature = "shared_from_slice2", since = "1.24.0"))] -impl From<&ZStr> for Arc { - #[inline] - fn from(s: &ZStr) -> Arc { - let arc: Arc<[u8]> = Arc::from(s.to_bytes_with_nul()); - unsafe { Arc::from_raw(Arc::into_raw(arc) as *const ZStr) } - } -} - -#[cfg_attr(staged_api, stable(feature = "shared_from_slice2", since = "1.24.0"))] -impl From for Rc { - /// Converts a [`ZString`] into an [Rc]<[ZStr]> without copying or allocating. - #[inline] - fn from(s: ZString) -> Rc { - let rc: Rc<[u8]> = Rc::from(s.into_inner()); - unsafe { Rc::from_raw(Rc::into_raw(rc) as *const ZStr) } - } -} - -#[cfg_attr(staged_api, stable(feature = "shared_from_slice2", since = "1.24.0"))] -impl From<&ZStr> for Rc { - #[inline] - fn from(s: &ZStr) -> Rc { - let rc: Rc<[u8]> = Rc::from(s.to_bytes_with_nul()); - unsafe { Rc::from_raw(Rc::into_raw(rc) as *const ZStr) } - } -} - -#[cfg_attr(staged_api, stable(feature = "default_box_extra", since = "1.17.0"))] -impl Default for Box { - fn default() -> Box { - let boxed: Box<[u8]> = Box::from([0]); - unsafe { Box::from_raw(Box::into_raw(boxed) as *mut ZStr) } - } -} - -impl NulError { - /// Returns the position of the nul byte in the slice that caused - /// [`ZString::new`] to fail. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZString; - /// - /// let nul_error = ZString::new("foo\0bar").unwrap_err(); - /// assert_eq!(nul_error.nul_position(), 3); - /// - /// let nul_error = ZString::new("foo bar\0").unwrap_err(); - /// assert_eq!(nul_error.nul_position(), 7); - /// ``` - #[must_use] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - pub fn nul_position(&self) -> usize { - self.0 - } - - /// Consumes this error, returning the underlying vector of bytes which - /// generated the error in the first place. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZString; - /// - /// let nul_error = ZString::new("foo\0bar").unwrap_err(); - /// assert_eq!(nul_error.into_vec(), b"foo\0bar"); - /// ``` - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - pub fn into_vec(self) -> Vec { - self.1 - } -} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl NulError { - /// ```rust - /// if let Err(e) = "xc".parse::() { - /// Print `e` itself, no need for description(). - /// eprintln!("Error: {}", e); - /// } - /// ``` - #[allow(deprecated)] - pub fn description(&self) -> &str { - "nul byte found in data" - } -} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl fmt::Display for NulError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "nul byte found in provided data at position: {}", self.0) - } -} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl From for io::Errno { - /// Converts a [`NulError`] into a [`io::Errno`]. - fn from(_: NulError) -> io::Errno { - io::Errno::INVAL - } -} - -#[cfg_attr( - staged_api, - stable(feature = "frombyteswithnulerror_impls", since = "1.17.0") -)] -impl FromBytesWithNulError { - /// ```rust - /// if let Err(e) = "xc".parse::() { - /// Print `e` itself, no need for description(). - /// eprintln!("Error: {}", e); - /// } - /// ``` - #[allow(deprecated)] - pub fn description(&self) -> &str { - match self.kind { - FromBytesWithNulErrorKind::InteriorNul(..) => { - "data provided contains an interior nul byte" - } - FromBytesWithNulErrorKind::NotNulTerminated => "data provided is not nul terminated", - } - } -} - -#[cfg_attr( - staged_api, - stable(feature = "frombyteswithnulerror_impls", since = "1.17.0") -)] -impl fmt::Display for FromBytesWithNulError { - #[allow(deprecated, deprecated_in_future)] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.description())?; - if let FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind { - write!(f, " at byte pos {}", pos)?; - } - Ok(()) - } -} - -#[cfg_attr( - staged_api, - stable(feature = "cstring_from_vec_with_nul", since = "1.58.0") -)] -impl fmt::Display for FromVecWithNulError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.error_kind { - FromBytesWithNulErrorKind::InteriorNul(pos) => { - write!( - f, - "data provided contains an interior nul byte at pos {}", - pos - ) - } - FromBytesWithNulErrorKind::NotNulTerminated => { - write!(f, "data provided is not nul terminated") - } - } - } -} - -impl IntoStringError { - /// Consumes this error, returning original [`ZString`] which generated the - /// error. - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr(staged_api, stable(feature = "cstring_into", since = "1.7.0"))] - pub fn into_zstring(self) -> ZString { - self.inner - } - - /// Consumes this error, returning original [`CString`] which generated the - /// error. - #[cfg(feature = "std")] - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr(staged_api, stable(feature = "cstring_into", since = "1.7.0"))] - pub fn into_cstring(self) -> CString { - self.into_zstring() - } - - /// Access the underlying UTF-8 error that was the cause of this error. - #[must_use] - #[cfg_attr(staged_api, stable(feature = "cstring_into", since = "1.7.0"))] - pub fn utf8_error(&self) -> Utf8Error { - self.error - } -} - -#[cfg_attr(staged_api, stable(feature = "cstring_into", since = "1.7.0"))] -impl IntoStringError { - #[allow(deprecated)] - pub fn description(&self) -> &str { - "C string contained non-utf8 bytes" - } - - /* TODO - pub fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(&self.error) - } - */ -} - -#[cfg_attr(staged_api, stable(feature = "cstring_into", since = "1.7.0"))] -impl fmt::Display for IntoStringError { - #[allow(deprecated, deprecated_in_future)] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.description().fmt(f) - } -} - -impl ZStr { - /// Wraps a raw C string with a safe C string wrapper. - /// - /// This function will wrap the provided `ptr` with a `ZStr` wrapper, which - /// allows inspection and interoperation of non-owned C strings. The total - /// size of the raw C string must be smaller than `isize::MAX` **bytes** - /// in memory due to calling the `slice::from_raw_parts` function. - /// This method is unsafe for a number of reasons: - /// - /// * There is no guarantee to the validity of `ptr`. - /// * The returned lifetime is not guaranteed to be the actual lifetime of - /// `ptr`. - /// * There is no guarantee that the memory pointed to by `ptr` contains a - /// valid nul terminator byte at the end of the string. - /// * It is not guaranteed that the memory pointed by `ptr` won't change - /// before the `ZStr` has been destroyed. - /// - /// > **Note**: This operation is intended to be a 0-cost cast but it is - /// > currently implemented with an up-front calculation of the length of - /// > the string. This is not guaranteed to always be the case. - /// - /// # Examples - /// - /// ```ignore (extern-declaration) - /// # fn main() { - /// use std::ffi::ZStr; - /// - /// extern "C" { - /// fn my_string() -> *const u8; - /// } - /// - /// unsafe { - /// let slice = ZStr::from_ptr(my_string()); - /// println!("string returned: {}", slice.to_str().unwrap()); - /// } - /// # } - /// ``` - #[inline] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - pub unsafe fn from_ptr<'a>(ptr: *const u8) -> &'a ZStr { - // SAFETY: The caller has provided a pointer that points to a valid C - // string with a NUL terminator of size less than `isize::MAX`, whose - // content remain valid and doesn't change for the lifetime of the - // returned `ZStr`. - // - // Thus computing the length is fine (a NUL byte exists), the call to - // from_raw_parts is safe because we know the length is at most `isize::MAX`, meaning - // the call to `from_bytes_with_nul_unchecked` is correct. - // - // The cast from u8 to u8 is ok because a u8 is always one byte. - unsafe { - let len = strlen(ptr); - ZStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1)) - } - } - - /// Creates a C string wrapper from a byte slice. - /// - /// This function will cast the provided `bytes` to a `ZStr` - /// wrapper after ensuring that the byte slice is nul-terminated - /// and does not contain any interior nul bytes. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZStr; - /// - /// let cstr = ZStr::from_bytes_with_nul(b"hello\0"); - /// assert!(cstr.is_ok()); - /// ``` - /// - /// Creating a `ZStr` without a trailing nul terminator is an error: - /// - /// ``` - /// use std::ffi::ZStr; - /// - /// let cstr = ZStr::from_bytes_with_nul(b"hello"); - /// assert!(cstr.is_err()); - /// ``` - /// - /// Creating a `ZStr` with an interior nul byte is an error: - /// - /// ``` - /// use std::ffi::ZStr; - /// - /// let cstr = ZStr::from_bytes_with_nul(b"he\0llo\0"); - /// assert!(cstr.is_err()); - /// ``` - #[cfg_attr(staged_api, stable(feature = "cstr_from_bytes", since = "1.10.0"))] - pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&ZStr, FromBytesWithNulError> { - let nul_pos = memchr(b'\0', bytes); - if let Some(nul_pos) = nul_pos { - if nul_pos + 1 != bytes.len() { - return Err(FromBytesWithNulError::interior_nul(nul_pos)); - } - Ok(unsafe { ZStr::from_bytes_with_nul_unchecked(bytes) }) - } else { - Err(FromBytesWithNulError::not_nul_terminated()) - } - } - - /// Unsafely creates a C string wrapper from a byte slice. - /// - /// This function will cast the provided `bytes` to a `ZStr` wrapper without - /// performing any sanity checks. The provided slice **must** be nul-terminated - /// and not contain any interior nul bytes. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::{ZStr, ZString}; - /// - /// unsafe { - /// let cstring = ZString::new("hello").expect("ZString::new failed"); - /// let cstr = ZStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul()); - /// assert_eq!(cstr, &*cstring); - /// } - /// ``` - #[cfg(const_raw_ptr_deref)] - #[inline] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "cstr_from_bytes", since = "1.10.0"))] - #[cfg_attr( - staged_api, - rustc_const_unstable(feature = "const_cstr_unchecked", issue = "90343") - )] - pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &ZStr { - // SAFETY: Casting to ZStr is safe because its internal representation - // is a [u8] too (safe only inside std). - // Dereferencing the obtained pointer is safe because it comes from a - // reference. Making a reference is then safe because its lifetime - // is bound by the lifetime of the given `bytes`. - unsafe { &*(bytes as *const [u8] as *const ZStr) } - } - - /// Unsafely creates a C string wrapper from a byte slice. - /// - /// This function will cast the provided `bytes` to a `ZStr` wrapper without - /// performing any sanity checks. The provided slice **must** be nul-terminated - /// and not contain any interior nul bytes. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::{ZStr, ZString}; - /// - /// unsafe { - /// let cstring = ZString::new("hello").expect("ZString::new failed"); - /// let cstr = ZStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul()); - /// assert_eq!(cstr, &*cstring); - /// } - /// ``` - #[cfg(not(const_raw_ptr_deref))] - #[inline] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "cstr_from_bytes", since = "1.10.0"))] - #[cfg_attr( - staged_api, - rustc_const_unstable(feature = "const_cstr_unchecked", issue = "90343") - )] - pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &ZStr { - // SAFETY: Casting to ZStr is safe because its internal representation - // is a [u8] too (safe only inside std). - // Dereferencing the obtained pointer is safe because it comes from a - // reference. Making a reference is then safe because its lifetime - // is bound by the lifetime of the given `bytes`. - unsafe { &*(bytes as *const [u8] as *const ZStr) } - } - - /// Returns the inner pointer to this C string. - /// - /// The returned pointer will be valid for as long as `self` is, and points - /// to a contiguous region of memory terminated with a 0 byte to represent - /// the end of the string. - /// - /// **WARNING** - /// - /// The returned pointer is read-only; writing to it (including passing it - /// to C code that writes to it) causes undefined behavior. - /// - /// It is your responsibility to make sure that the underlying memory is not - /// freed too early. For example, the following code will cause undefined - /// behavior when `ptr` is used inside the `unsafe` block: - /// - /// ```no_run - /// # #![allow(unused_must_use)] #![allow(temporary_cstring_as_ptr)] - /// use std::ffi::ZString; - /// - /// let ptr = ZString::new("Hello").expect("ZString::new failed").as_ptr(); - /// unsafe { - /// // `ptr` is dangling - /// *ptr; - /// } - /// ``` - /// - /// This happens because the pointer returned by `as_ptr` does not carry any - /// lifetime information and the [`ZString`] is deallocated immediately after - /// the `ZString::new("Hello").expect("ZString::new failed").as_ptr()` - /// expression is evaluated. - /// To fix the problem, bind the `ZString` to a local variable: - /// - /// ```no_run - /// # #![allow(unused_must_use)] - /// use std::ffi::ZString; - /// - /// let hello = ZString::new("Hello").expect("ZString::new failed"); - /// let ptr = hello.as_ptr(); - /// unsafe { - /// // `ptr` is valid because `hello` is in scope - /// *ptr; - /// } - /// ``` - /// - /// This way, the lifetime of the [`ZString`] in `hello` encompasses - /// the lifetime of `ptr` and the `unsafe` block. - #[inline] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - #[cfg_attr( - staged_api, - rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0") - )] - pub const fn as_ptr(&self) -> *const u8 { - self.inner.as_ptr() - } - - /// Converts this C string to a byte slice. - /// - /// The returned slice will **not** contain the trailing nul terminator that this C - /// string has. - /// - /// > **Note**: This method is currently implemented as a constant-time - /// > cast, but it is planned to alter its definition in the future to - /// > perform the length calculation whenever this method is called. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZStr; - /// - /// let cstr = ZStr::from_bytes_with_nul(b"foo\0").expect("ZStr::from_bytes_with_nul failed"); - /// assert_eq!(cstr.to_bytes(), b"foo"); - /// ``` - #[inline] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - pub fn to_bytes(&self) -> &[u8] { - let bytes = self.to_bytes_with_nul(); - // SAFETY: to_bytes_with_nul returns slice with length at least 1 - unsafe { bytes.get_unchecked(..bytes.len() - 1) } - } - - /// Converts this C string to a byte slice containing the trailing 0 byte. - /// - /// This function is the equivalent of [`ZStr::to_bytes`] except that it - /// will retain the trailing nul terminator instead of chopping it off. - /// - /// > **Note**: This method is currently implemented as a 0-cost cast, but - /// > it is planned to alter its definition in the future to perform the - /// > length calculation whenever this method is called. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZStr; - /// - /// let cstr = ZStr::from_bytes_with_nul(b"foo\0").expect("ZStr::from_bytes_with_nul failed"); - /// assert_eq!(cstr.to_bytes_with_nul(), b"foo\0"); - /// ``` - #[inline] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - pub fn to_bytes_with_nul(&self) -> &[u8] { - unsafe { &*(&self.inner as *const [u8]) } - } - - /// Yields a &[str] slice if the `ZStr` contains valid UTF-8. - /// - /// If the contents of the `ZStr` are valid UTF-8 data, this - /// function will return the corresponding &[str] slice. Otherwise, - /// it will return an error with details of where UTF-8 validation failed. - /// - /// [str]: prim@str "str" - /// - /// # Examples - /// - /// ``` - /// use std::ffi::ZStr; - /// - /// let cstr = ZStr::from_bytes_with_nul(b"foo\0").expect("ZStr::from_bytes_with_nul failed"); - /// assert_eq!(cstr.to_str(), Ok("foo")); - /// ``` - #[cfg_attr(staged_api, stable(feature = "cstr_to_str", since = "1.4.0"))] - pub fn to_str(&self) -> Result<&str, str::Utf8Error> { - // N.B., when `ZStr` is changed to perform the length check in `.to_bytes()` - // instead of in `from_ptr()`, it may be worth considering if this should - // be rewritten to do the UTF-8 check inline with the length calculation - // instead of doing it afterwards. - str::from_utf8(self.to_bytes()) - } - - /// Converts a `ZStr` into a [Cow]<[str]>. - /// - /// If the contents of the `ZStr` are valid UTF-8 data, this - /// function will return a [Cow]::[Borrowed]\(&[str]) - /// with the corresponding &[str] slice. Otherwise, it will - /// replace any invalid UTF-8 sequences with - /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a - /// [Cow]::[Owned]\(&[str]) with the result. - /// - /// [str]: prim@str "str" - /// [Borrowed]: Cow::Borrowed - /// [Owned]: Cow::Owned - /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER "std::char::REPLACEMENT_CHARACTER" - /// - /// # Examples - /// - /// Calling `to_string_lossy` on a `ZStr` containing valid UTF-8: - /// - /// ``` - /// use std::borrow::Cow; - /// use std::ffi::ZStr; - /// - /// let cstr = ZStr::from_bytes_with_nul(b"Hello World\0") - /// .expect("ZStr::from_bytes_with_nul failed"); - /// assert_eq!(cstr.to_string_lossy(), Cow::Borrowed("Hello World")); - /// ``` - /// - /// Calling `to_string_lossy` on a `ZStr` containing invalid UTF-8: - /// - /// ``` - /// use std::borrow::Cow; - /// use std::ffi::ZStr; - /// - /// let cstr = ZStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0") - /// .expect("ZStr::from_bytes_with_nul failed"); - /// assert_eq!( - /// cstr.to_string_lossy(), - /// Cow::Owned(String::from("Hello �World")) as Cow<'_, str> - /// ); - /// ``` - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[cfg_attr(staged_api, stable(feature = "cstr_to_str", since = "1.4.0"))] - pub fn to_string_lossy(&self) -> Cow<'_, str> { - String::from_utf8_lossy(self.to_bytes()) - } - - /// Converts a [Box]<[ZStr]> into a [`ZString`] without copying or allocating. - /// - /// # Examples - /// - /// ``` - /// use rustix::ffi::ZString; - /// - /// let z_string = ZString::new(b"foo".to_vec()).expect("ZString::new failed"); - /// let boxed = z_string.into_boxed_z_str(); - /// assert_eq!(boxed.into_z_string(), ZString::new("foo").expect("ZString::new failed")); - /// ``` - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr(staged_api, stable(feature = "into_boxed_c_str", since = "1.20.0"))] - pub fn into_z_string(self: Box) -> ZString { - let raw = Box::into_raw(self) as *mut [u8]; - ZString { - inner: unsafe { Box::from_raw(raw) }, - } - } - - /// Converts a [Box]<[ZStr]> into a [`CString`] without copying or allocating. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::CString; - /// use rustix::ffi::ZString; - /// - /// let z_string = ZString::new(b"foo".to_vec()).expect("ZString::new failed"); - /// let boxed = z_string.into_boxed_z_str(); - /// assert_eq!(boxed.into_c_string(), CString::new("foo").expect("ZString::new failed")); - /// ``` - #[cfg(feature = "std")] - #[must_use = "`self` will be dropped if the result is not used"] - #[cfg_attr(staged_api, stable(feature = "into_boxed_c_str", since = "1.20.0"))] - pub fn into_c_string(self: Box) -> CString { - self.into_z_string() - } -} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl PartialEq for ZStr { - fn eq(&self, other: &ZStr) -> bool { - self.to_bytes().eq(other.to_bytes()) - } -} -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl Eq for ZStr {} -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl PartialOrd for ZStr { - fn partial_cmp(&self, other: &ZStr) -> Option { - self.to_bytes().partial_cmp(&other.to_bytes()) - } -} -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl Ord for ZStr { - fn cmp(&self, other: &ZStr) -> Ordering { - self.to_bytes().cmp(&other.to_bytes()) - } -} - -#[cfg_attr(staged_api, stable(feature = "cstr_borrow", since = "1.3.0"))] -impl ToOwned for ZStr { - type Owned = ZString; - - fn to_owned(&self) -> ZString { - ZString { - inner: self.to_bytes_with_nul().into(), - } - } - - #[cfg(toowned_clone_into)] - fn clone_into(&self, target: &mut ZString) { - let mut b = Vec::from(mem::take(&mut target.inner)); - self.to_bytes_with_nul().clone_into(&mut b); - target.inner = b.into_boxed_slice(); - } -} - -#[cfg_attr(staged_api, stable(feature = "cstring_asref", since = "1.7.0"))] -impl From<&ZStr> for ZString { - fn from(s: &ZStr) -> ZString { - s.to_owned() - } -} - -#[cfg_attr(staged_api, stable(feature = "cstring_asref", since = "1.7.0"))] -impl ops::Index for ZString { - type Output = ZStr; - - #[inline] - fn index(&self, _index: ops::RangeFull) -> &ZStr { - self - } -} - -#[cfg_attr(staged_api, stable(feature = "cstr_range_from", since = "1.47.0"))] -impl ops::Index> for ZStr { - type Output = ZStr; - - fn index(&self, index: ops::RangeFrom) -> &ZStr { - let bytes = self.to_bytes_with_nul(); - // we need to manually check the starting index to account for the null - // byte, since otherwise we could get an empty string that doesn't end - // in a null. - if index.start < bytes.len() { - unsafe { ZStr::from_bytes_with_nul_unchecked(&bytes[index.start..]) } - } else { - panic!( - "index out of bounds: the len is {} but the index is {}", - bytes.len(), - index.start - ); - } - } -} - -#[cfg_attr(staged_api, stable(feature = "cstring_asref", since = "1.7.0"))] -impl AsRef for ZStr { - #[inline] - fn as_ref(&self) -> &ZStr { - self - } -} - -#[cfg_attr(staged_api, stable(feature = "cstring_asref", since = "1.7.0"))] -impl AsRef for ZString { - #[inline] - fn as_ref(&self) -> &ZStr { - self - } -} diff --git a/src/fs/abs.rs b/src/fs/abs.rs index 7a8c7bcd8..6c91a41ce 100644 --- a/src/fs/abs.rs +++ b/src/fs/abs.rs @@ -29,5 +29,5 @@ use crate::{imp, io, path}; )))] #[inline] pub fn statfs(path: P) -> io::Result { - path.into_with_z_str(imp::fs::syscalls::statfs) + path.into_with_c_str(imp::fs::syscalls::statfs) } diff --git a/src/fs/at.rs b/src/fs/at.rs index 16fe6b9cd..795838b15 100644 --- a/src/fs/at.rs +++ b/src/fs/at.rs @@ -5,7 +5,7 @@ //! //! [`cwd`]: crate::fs::cwd -use crate::ffi::{ZStr, ZString}; +use crate::ffi::{CStr, CString}; #[cfg(not(target_os = "illumos"))] use crate::fs::Access; #[cfg(any(target_os = "ios", target_os = "macos"))] @@ -59,7 +59,7 @@ pub fn openat( oflags: OFlags, create_mode: Mode, ) -> io::Result { - path.into_with_z_str(|path| imp::fs::syscalls::openat(dirfd.as_fd(), path, oflags, create_mode)) + path.into_with_c_str(|path| imp::fs::syscalls::openat(dirfd.as_fd(), path, oflags, create_mode)) } /// `readlinkat(fd, path)`—Reads the contents of a symlink. @@ -77,11 +77,11 @@ pub fn readlinkat>>( dirfd: Fd, path: P, reuse: B, -) -> io::Result { - path.into_with_z_str(|path| _readlinkat(dirfd.as_fd(), path, reuse.into())) +) -> io::Result { + path.into_with_c_str(|path| _readlinkat(dirfd.as_fd(), path, reuse.into())) } -fn _readlinkat(dirfd: BorrowedFd<'_>, path: &ZStr, mut buffer: Vec) -> io::Result { +fn _readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, mut buffer: Vec) -> io::Result { // This code would benefit from having a better way to read into // uninitialized memory, but that requires `unsafe`. buffer.clear(); @@ -95,7 +95,7 @@ fn _readlinkat(dirfd: BorrowedFd<'_>, path: &ZStr, mut buffer: Vec) -> io::R assert!(nread <= buffer.len()); if nread < buffer.len() { buffer.resize(nread, 0_u8); - return Ok(ZString::new(buffer).unwrap()); + return Ok(CString::new(buffer).unwrap()); } buffer.reserve(1); // use `Vec` reallocation strategy to grow capacity exponentially buffer.resize(buffer.capacity(), 0_u8); @@ -112,7 +112,7 @@ fn _readlinkat(dirfd: BorrowedFd<'_>, path: &ZStr, mut buffer: Vec) -> io::R /// [Linux]: https://man7.org/linux/man-pages/man2/mkdirat.2.html #[inline] pub fn mkdirat(dirfd: Fd, path: P, mode: Mode) -> io::Result<()> { - path.into_with_z_str(|path| imp::fs::syscalls::mkdirat(dirfd.as_fd(), path, mode)) + path.into_with_c_str(|path| imp::fs::syscalls::mkdirat(dirfd.as_fd(), path, mode)) } /// `linkat(old_dirfd, old_path, new_dirfd, new_path, flags)`—Creates a hard @@ -132,8 +132,8 @@ pub fn linkat( new_path: Q, flags: AtFlags, ) -> io::Result<()> { - old_path.into_with_z_str(|old_path| { - new_path.into_with_z_str(|new_path| { + old_path.into_with_c_str(|old_path| { + new_path.into_with_c_str(|new_path| { imp::fs::syscalls::linkat( old_dirfd.as_fd(), old_path, @@ -159,7 +159,7 @@ pub fn linkat( /// [Linux]: https://man7.org/linux/man-pages/man2/unlinkat.2.html #[inline] pub fn unlinkat(dirfd: Fd, path: P, flags: AtFlags) -> io::Result<()> { - path.into_with_z_str(|path| imp::fs::syscalls::unlinkat(dirfd.as_fd(), path, flags)) + path.into_with_c_str(|path| imp::fs::syscalls::unlinkat(dirfd.as_fd(), path, flags)) } /// `renameat(old_dirfd, old_path, new_dirfd, new_path)`—Renames a file or @@ -178,8 +178,8 @@ pub fn renameat( new_dirfd: QFd, new_path: Q, ) -> io::Result<()> { - old_path.into_with_z_str(|old_path| { - new_path.into_with_z_str(|new_path| { + old_path.into_with_c_str(|old_path| { + new_path.into_with_c_str(|new_path| { imp::fs::syscalls::renameat(old_dirfd.as_fd(), old_path, new_dirfd.as_fd(), new_path) }) }) @@ -202,8 +202,8 @@ pub fn renameat_with( new_path: Q, flags: RenameFlags, ) -> io::Result<()> { - old_path.into_with_z_str(|old_path| { - new_path.into_with_z_str(|new_path| { + old_path.into_with_c_str(|old_path| { + new_path.into_with_c_str(|new_path| { imp::fs::syscalls::renameat2( old_dirfd.as_fd(), old_path, @@ -229,8 +229,8 @@ pub fn symlinkat( new_dirfd: Fd, new_path: Q, ) -> io::Result<()> { - old_path.into_with_z_str(|old_path| { - new_path.into_with_z_str(|new_path| { + old_path.into_with_c_str(|old_path| { + new_path.into_with_c_str(|new_path| { imp::fs::syscalls::symlinkat(old_path, new_dirfd.as_fd(), new_path) }) }) @@ -252,7 +252,7 @@ pub fn symlinkat( #[inline] #[doc(alias = "fstatat")] pub fn statat(dirfd: Fd, path: P, flags: AtFlags) -> io::Result { - path.into_with_z_str(|path| imp::fs::syscalls::statat(dirfd.as_fd(), path, flags)) + path.into_with_c_str(|path| imp::fs::syscalls::statat(dirfd.as_fd(), path, flags)) } /// `faccessat(dirfd, path, access, flags)`—Tests permissions for a file or @@ -273,7 +273,7 @@ pub fn accessat( access: Access, flags: AtFlags, ) -> io::Result<()> { - path.into_with_z_str(|path| imp::fs::syscalls::accessat(dirfd.as_fd(), path, access, flags)) + path.into_with_c_str(|path| imp::fs::syscalls::accessat(dirfd.as_fd(), path, access, flags)) } /// `utimensat(dirfd, path, times, flags)`—Sets file or directory timestamps. @@ -291,7 +291,7 @@ pub fn utimensat( times: &Timestamps, flags: AtFlags, ) -> io::Result<()> { - path.into_with_z_str(|path| imp::fs::syscalls::utimensat(dirfd.as_fd(), path, times, flags)) + path.into_with_c_str(|path| imp::fs::syscalls::utimensat(dirfd.as_fd(), path, times, flags)) } /// `fchmodat(dirfd, path, mode, 0)`—Sets file or directory permissions. @@ -312,7 +312,7 @@ pub fn utimensat( #[inline] #[doc(alias = "fchmodat")] pub fn chmodat(dirfd: Fd, path: P, mode: Mode) -> io::Result<()> { - path.into_with_z_str(|path| imp::fs::syscalls::chmodat(dirfd.as_fd(), path, mode)) + path.into_with_c_str(|path| imp::fs::syscalls::chmodat(dirfd.as_fd(), path, mode)) } /// `fclonefileat(src, dst_dir, dst, flags)`—Efficiently copies between files. @@ -329,7 +329,7 @@ pub fn fclonefileat( dst: P, flags: CloneFlags, ) -> io::Result<()> { - dst.into_with_z_str(|dst| { + dst.into_with_c_str(|dst| { imp::fs::syscalls::fclonefileat(src.as_fd(), dst_dir.as_fd(), &dst, flags) }) } @@ -351,7 +351,7 @@ pub fn mknodat( mode: Mode, dev: Dev, ) -> io::Result<()> { - path.into_with_z_str(|path| { + path.into_with_c_str(|path| { imp::fs::syscalls::mknodat(dirfd.as_fd(), path, file_type, mode, dev) }) } @@ -374,7 +374,7 @@ pub fn chownat( group: Gid, flags: AtFlags, ) -> io::Result<()> { - path.into_with_z_str(|path| { + path.into_with_c_str(|path| { imp::fs::syscalls::chownat(dirfd.as_fd(), path, owner, group, flags) }) } diff --git a/src/fs/getpath.rs b/src/fs/getpath.rs index f86849f0a..bc40890d1 100644 --- a/src/fs/getpath.rs +++ b/src/fs/getpath.rs @@ -1,4 +1,4 @@ -use crate::ffi::ZString; +use crate::ffi::CString; use crate::{imp, io}; use imp::fd::AsFd; @@ -9,6 +9,6 @@ use imp::fd::AsFd; /// /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html #[inline] -pub fn getpath(fd: Fd) -> io::Result { +pub fn getpath(fd: Fd) -> io::Result { imp::fs::syscalls::getpath(fd.as_fd()) } diff --git a/src/fs/memfd_create.rs b/src/fs/memfd_create.rs index 68546f112..74b432739 100644 --- a/src/fs/memfd_create.rs +++ b/src/fs/memfd_create.rs @@ -11,5 +11,5 @@ pub use imp::fs::types::MemfdFlags; /// [Linux]: https://man7.org/linux/man-pages/man2/memfd_create.2.html #[inline] pub fn memfd_create(path: P, flags: MemfdFlags) -> io::Result { - path.into_with_z_str(|path| imp::fs::syscalls::memfd_create(path, flags)) + path.into_with_c_str(|path| imp::fs::syscalls::memfd_create(path, flags)) } diff --git a/src/fs/openat2.rs b/src/fs/openat2.rs index b0eb7702d..d6f77357b 100644 --- a/src/fs/openat2.rs +++ b/src/fs/openat2.rs @@ -17,7 +17,7 @@ pub fn openat2( mode: Mode, resolve: ResolveFlags, ) -> io::Result { - path.into_with_z_str(|path| { + path.into_with_c_str(|path| { imp::fs::syscalls::openat2(dirfd.as_fd(), path, oflags, mode, resolve) }) } diff --git a/src/fs/statx.rs b/src/fs/statx.rs index 0bf63b00f..c6165b2c7 100644 --- a/src/fs/statx.rs +++ b/src/fs/statx.rs @@ -22,5 +22,5 @@ pub fn statx( flags: AtFlags, mask: StatxFlags, ) -> io::Result { - path.into_with_z_str(|path| imp::fs::syscalls::statx(dirfd.as_fd(), path, flags, mask)) + path.into_with_c_str(|path| imp::fs::syscalls::statx(dirfd.as_fd(), path, flags, mask)) } diff --git a/src/imp/libc/conv.rs b/src/imp/libc/conv.rs index 85f4da5c6..348006b61 100644 --- a/src/imp/libc/conv.rs +++ b/src/imp/libc/conv.rs @@ -9,14 +9,14 @@ use super::fd::{AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, LibcFd, RawFd}; #[cfg(not(windows))] use super::offset::libc_off_t; #[cfg(not(windows))] -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::io::{self, OwnedFd}; #[cfg(windows)] use core::convert::TryInto; #[cfg(not(windows))] #[inline] -pub(super) fn c_str(c: &ZStr) -> *const c::c_char { +pub(super) fn c_str(c: &CStr) -> *const c::c_char { c.as_ptr().cast::() } diff --git a/src/imp/libc/fs/dir.rs b/src/imp/libc/fs/dir.rs index 19e0feb41..ae9555f87 100644 --- a/src/imp/libc/fs/dir.rs +++ b/src/imp/libc/fs/dir.rs @@ -3,9 +3,9 @@ use super::super::conv::owned_fd; #[cfg(not(target_os = "illumos"))] use super::types::FileType; use crate::fd::{AsFd, BorrowedFd}; -use crate::ffi::ZStr; +use crate::ffi::CStr; #[cfg(target_os = "wasi")] -use crate::ffi::ZString; +use crate::ffi::CString; use crate::fs::{fcntl_getfl, fstat, openat, Mode, OFlags, Stat}; #[cfg(not(any( target_os = "illumos", @@ -66,7 +66,7 @@ impl Dir { // our call to `fdopendir`. To prevent this, we obtain an independent // `OwnedFd`. let flags = fcntl_getfl(&fd)?; - let fd_for_dir = openat(&fd, zstr!("."), flags | OFlags::CLOEXEC, Mode::empty())?; + let fd_for_dir = openat(&fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty())?; let raw = owned_fd(fd_for_dir); unsafe { @@ -113,7 +113,7 @@ impl Dir { dirent: read_dirent(&*dirent_ptr.cast()), #[cfg(target_os = "wasi")] - name: ZStr::from_ptr((*dirent_ptr).d_name.as_ptr().cast()).to_owned(), + name: CStr::from_ptr((*dirent_ptr).d_name.as_ptr().cast()).to_owned(), }; Some(Ok(result)) @@ -244,7 +244,7 @@ unsafe fn read_dirent(input: &libc_dirent) -> libc_dirent { // Copy from d_name, reading up to and including the first NUL. #[cfg(not(target_os = "wasi"))] { - let name_len = ZStr::from_ptr(input.d_name.as_ptr().cast()) + let name_len = CStr::from_ptr(input.d_name.as_ptr().cast()) .to_bytes() .len() + 1; @@ -290,16 +290,16 @@ pub struct DirEntry { dirent: libc_dirent, #[cfg(target_os = "wasi")] - name: ZString, + name: CString, } impl DirEntry { /// Returns the file name of this directory entry. #[inline] - pub fn file_name(&self) -> &ZStr { + pub fn file_name(&self) -> &CStr { #[cfg(not(target_os = "wasi"))] unsafe { - ZStr::from_ptr(self.dirent.d_name.as_ptr().cast()) + CStr::from_ptr(self.dirent.d_name.as_ptr().cast()) } #[cfg(target_os = "wasi")] diff --git a/src/imp/libc/fs/syscalls.rs b/src/imp/libc/fs/syscalls.rs index a30c89ea0..35b8e4da2 100644 --- a/src/imp/libc/fs/syscalls.rs +++ b/src/imp/libc/fs/syscalls.rs @@ -47,9 +47,9 @@ use super::super::time::types::LibcTimespec; use crate::fd::BorrowedFd; #[cfg(not(target_os = "wasi"))] use crate::fd::RawFd; -use crate::ffi::ZStr; +use crate::ffi::CStr; #[cfg(any(target_os = "ios", target_os = "macos"))] -use crate::ffi::ZString; +use crate::ffi::CString; #[cfg(not(target_os = "illumos"))] use crate::fs::Access; #[cfg(not(any( @@ -153,7 +153,7 @@ weak!(fn __futimens64(c::c_int, *const LibcTimespec) -> c::c_int); #[cfg(all(unix, target_env = "gnu"))] fn openat_via_syscall( dirfd: BorrowedFd<'_>, - path: &ZStr, + path: &CStr, oflags: OFlags, mode: Mode, ) -> io::Result { @@ -175,7 +175,7 @@ fn openat_via_syscall( #[cfg(not(target_os = "redox"))] pub(crate) fn openat( dirfd: BorrowedFd<'_>, - path: &ZStr, + path: &CStr, oflags: OFlags, mode: Mode, ) -> io::Result { @@ -205,7 +205,7 @@ pub(crate) fn openat( target_os = "wasi" )))] #[inline] -pub(crate) fn statfs(filename: &ZStr) -> io::Result { +pub(crate) fn statfs(filename: &CStr) -> io::Result { unsafe { let mut result = MaybeUninit::::uninit(); ret(libc_statfs(c_str(filename), result.as_mut_ptr()))?; @@ -215,7 +215,7 @@ pub(crate) fn statfs(filename: &ZStr) -> io::Result { #[cfg(not(target_os = "redox"))] #[inline] -pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &ZStr, buf: &mut [u8]) -> io::Result { +pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, buf: &mut [u8]) -> io::Result { unsafe { ret_ssize_t(c::readlinkat( borrowed_fd(dirfd), @@ -228,7 +228,7 @@ pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &ZStr, buf: &mut [u8]) -> } #[cfg(not(target_os = "redox"))] -pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, path: &ZStr, mode: Mode) -> io::Result<()> { +pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { unsafe { ret(c::mkdirat( borrowed_fd(dirfd), @@ -241,9 +241,9 @@ pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, path: &ZStr, mode: Mode) -> io::Res #[cfg(not(target_os = "redox"))] pub(crate) fn linkat( old_dirfd: BorrowedFd<'_>, - old_path: &ZStr, + old_path: &CStr, new_dirfd: BorrowedFd<'_>, - new_path: &ZStr, + new_path: &CStr, flags: AtFlags, ) -> io::Result<()> { unsafe { @@ -258,16 +258,16 @@ pub(crate) fn linkat( } #[cfg(not(target_os = "redox"))] -pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, path: &ZStr, flags: AtFlags) -> io::Result<()> { +pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<()> { unsafe { ret(c::unlinkat(borrowed_fd(dirfd), c_str(path), flags.bits())) } } #[cfg(not(target_os = "redox"))] pub(crate) fn renameat( old_dirfd: BorrowedFd<'_>, - old_path: &ZStr, + old_path: &CStr, new_dirfd: BorrowedFd<'_>, - new_path: &ZStr, + new_path: &CStr, ) -> io::Result<()> { unsafe { ret(c::renameat( @@ -282,9 +282,9 @@ pub(crate) fn renameat( #[cfg(all(target_os = "linux", target_env = "gnu"))] pub(crate) fn renameat2( old_dirfd: BorrowedFd<'_>, - old_path: &ZStr, + old_path: &CStr, new_dirfd: BorrowedFd<'_>, - new_path: &ZStr, + new_path: &CStr, flags: RenameFlags, ) -> io::Result<()> { // `getrandom` wasn't supported in glibc until 2.28. @@ -318,9 +318,9 @@ pub(crate) fn renameat2( #[inline] pub(crate) fn renameat2( old_dirfd: BorrowedFd<'_>, - old_path: &ZStr, + old_path: &CStr, new_dirfd: BorrowedFd<'_>, - new_path: &ZStr, + new_path: &CStr, flags: RenameFlags, ) -> io::Result<()> { assert!(flags.is_empty()); @@ -329,9 +329,9 @@ pub(crate) fn renameat2( #[cfg(not(target_os = "redox"))] pub(crate) fn symlinkat( - old_path: &ZStr, + old_path: &CStr, new_dirfd: BorrowedFd<'_>, - new_path: &ZStr, + new_path: &CStr, ) -> io::Result<()> { unsafe { ret(c::symlinkat( @@ -343,7 +343,7 @@ pub(crate) fn symlinkat( } #[cfg(not(target_os = "redox"))] -pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &ZStr, flags: AtFlags) -> io::Result { +pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result { // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use // `statx`. #[cfg(all( @@ -383,7 +383,7 @@ pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &ZStr, flags: AtFlags) -> io:: any(target_os = "android", target_os = "linux"), any(target_pointer_width = "32", target_arch = "mips64") ))] -fn statat_old(dirfd: BorrowedFd<'_>, path: &ZStr, flags: AtFlags) -> io::Result { +fn statat_old(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result { unsafe { let mut result = MaybeUninit::::uninit(); ret(libc_fstatat( @@ -399,7 +399,7 @@ fn statat_old(dirfd: BorrowedFd<'_>, path: &ZStr, flags: AtFlags) -> io::Result< #[cfg(not(any(target_os = "emscripten", target_os = "illumos", target_os = "redox")))] pub(crate) fn accessat( dirfd: BorrowedFd<'_>, - path: &ZStr, + path: &CStr, access: Access, flags: AtFlags, ) -> io::Result<()> { @@ -416,7 +416,7 @@ pub(crate) fn accessat( #[cfg(target_os = "emscripten")] pub(crate) fn accessat( _dirfd: BorrowedFd<'_>, - _path: &ZStr, + _path: &CStr, _access: Access, _flags: AtFlags, ) -> io::Result<()> { @@ -426,7 +426,7 @@ pub(crate) fn accessat( #[cfg(not(target_os = "redox"))] pub(crate) fn utimensat( dirfd: BorrowedFd<'_>, - path: &ZStr, + path: &CStr, times: &Timestamps, flags: AtFlags, ) -> io::Result<()> { @@ -597,7 +597,7 @@ pub(crate) fn utimensat( ))] unsafe fn utimensat_old( dirfd: BorrowedFd<'_>, - path: &ZStr, + path: &CStr, times: &Timestamps, flags: AtFlags, ) -> io::Result<()> { @@ -633,12 +633,12 @@ unsafe fn utimensat_old( target_os = "redox", target_os = "wasi", )))] -pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &ZStr, mode: Mode) -> io::Result<()> { +pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { unsafe { ret(c::fchmodat(borrowed_fd(dirfd), c_str(path), mode.bits(), 0)) } } #[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &ZStr, mode: Mode) -> io::Result<()> { +pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { // Linux's `fchmodat` does not have a flags argument. unsafe { // Pass `mode` as a `c_uint` even if `mode_t` is narrower, since @@ -657,7 +657,7 @@ pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &ZStr, mode: Mode) -> io::Res pub(crate) fn fclonefileat( srcfd: BorrowedFd<'_>, dst_dirfd: BorrowedFd<'_>, - dst: &ZStr, + dst: &CStr, flags: CloneFlags, ) -> io::Result<()> { syscall! { @@ -675,7 +675,7 @@ pub(crate) fn fclonefileat( #[cfg(not(any(target_os = "redox", target_os = "wasi")))] pub(crate) fn chownat( dirfd: BorrowedFd<'_>, - path: &ZStr, + path: &CStr, owner: Uid, group: Gid, flags: AtFlags, @@ -699,7 +699,7 @@ pub(crate) fn chownat( )))] pub(crate) fn mknodat( dirfd: BorrowedFd<'_>, - path: &ZStr, + path: &CStr, file_type: FileType, mode: Mode, dev: Dev, @@ -920,7 +920,7 @@ pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result { ))] { if !NO_STATX.load(Relaxed) { - match statx(fd, zstr!(""), AtFlags::EMPTY_PATH, StatxFlags::ALL) { + match statx(fd, cstr!(""), AtFlags::EMPTY_PATH, StatxFlags::ALL) { Ok(x) => return statx_to_stat(x), Err(io::Errno::NOSYS) => NO_STATX.store(true, Relaxed), Err(e) => return Err(e), @@ -1156,7 +1156,7 @@ pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> { } #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] -pub(crate) fn memfd_create(path: &ZStr, flags: MemfdFlags) -> io::Result { +pub(crate) fn memfd_create(path: &CStr, flags: MemfdFlags) -> io::Result { #[cfg(target_os = "freebsd")] weakcall! { fn memfd_create( @@ -1179,7 +1179,7 @@ pub(crate) fn memfd_create(path: &ZStr, flags: MemfdFlags) -> io::Result, - path: &ZStr, + path: &CStr, oflags: OFlags, mode: Mode, resolve: ResolveFlags, @@ -1403,7 +1403,7 @@ fn stat64_to_stat(s64: c::stat64) -> io::Result { #[allow(non_upper_case_globals)] pub(crate) fn statx( dirfd: BorrowedFd<'_>, - path: &ZStr, + path: &CStr, flags: AtFlags, mask: StatxFlags, ) -> io::Result { @@ -1510,7 +1510,7 @@ pub(crate) unsafe fn copyfile_state_get( } #[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) fn getpath(fd: BorrowedFd<'_>) -> io::Result { +pub(crate) fn getpath(fd: BorrowedFd<'_>) -> io::Result { // The use of PATH_MAX is generally not encouraged, but it // is inevitable in this case because macOS defines `fcntl` with // `F_GETPATH` in terms of `MAXPATHLEN`, and there are no @@ -1534,7 +1534,7 @@ pub(crate) fn getpath(fd: BorrowedFd<'_>) -> io::Result { //buf.shrink_to(l + 1); buf.shrink_to_fit(); - Ok(ZString::new(buf).unwrap()) + Ok(CString::new(buf).unwrap()) } #[cfg(any(target_os = "ios", target_os = "macos"))] diff --git a/src/imp/libc/net/addr.rs b/src/imp/libc/net/addr.rs index 4e4801b77..f7d0e869f 100644 --- a/src/imp/libc/net/addr.rs +++ b/src/imp/libc/net/addr.rs @@ -2,7 +2,7 @@ use super::super::c; #[cfg(unix)] -use crate::ffi::ZStr; +use crate::ffi::CStr; #[cfg(unix)] use crate::io; #[cfg(unix)] @@ -36,11 +36,11 @@ impl SocketAddrUnix { /// Construct a new Unix-domain address from a filesystem path. #[inline] pub fn new(path: P) -> io::Result { - path.into_with_z_str(Self::_new) + path.into_with_c_str(Self::_new) } #[inline] - fn _new(path: &ZStr) -> io::Result { + fn _new(path: &CStr) -> io::Result { let mut unix = Self::init(); let bytes = path.to_bytes_with_nul(); if bytes.len() > unix.sun_path.len() { @@ -139,7 +139,7 @@ impl SocketAddrUnix { /// For a filesystem path address, return the path. #[inline] - pub fn path(&self) -> Option<&ZStr> { + pub fn path(&self) -> Option<&CStr> { let len = self.len(); if len != 0 && self.unix.sun_path[0] != b'\0' as c::c_char { let end = len as usize - offsetof_sun_path(); @@ -147,7 +147,7 @@ impl SocketAddrUnix { // Safety: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. And // `from_bytes_with_nul_unchecked` since the string is NUL-terminated. unsafe { - Some(ZStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( + Some(CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( bytes.as_ptr().cast(), bytes.len(), ))) diff --git a/src/imp/libc/net/read_sockaddr.rs b/src/imp/libc/net/read_sockaddr.rs index cda6eca5d..ab4753850 100644 --- a/src/imp/libc/net/read_sockaddr.rs +++ b/src/imp/libc/net/read_sockaddr.rs @@ -3,7 +3,7 @@ use super::super::c; use super::addr::SocketAddrUnix; use super::ext::{in6_addr_s6_addr, in_addr_s_addr, sockaddr_in6_sin6_scope_id}; #[cfg(not(windows))] -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::io; use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrV4, SocketAddrV6}; #[cfg(not(windows))] @@ -149,7 +149,7 @@ pub(crate) unsafe fn read_sockaddr( return Err(io::Errno::INVAL); } debug_assert_eq!( - ZStr::from_ptr(decode.sun_path.as_ptr().cast()) + CStr::from_ptr(decode.sun_path.as_ptr().cast()) .to_bytes() .len(), provided_len diff --git a/src/imp/libc/process/auxv.rs b/src/imp/libc/process/auxv.rs index 2319d2de2..71a2572ae 100644 --- a/src/imp/libc/process/auxv.rs +++ b/src/imp/libc/process/auxv.rs @@ -3,7 +3,7 @@ use super::super::c; all(target_os = "android", target_pointer_width = "64"), target_os = "linux" ))] -use crate::ffi::ZStr; +use crate::ffi::CStr; // `getauxval` wasn't supported in glibc until 2.16. #[cfg(any( @@ -45,10 +45,10 @@ pub(crate) fn linux_hwcap() -> (usize, usize) { target_os = "linux" ))] #[inline] -pub(crate) fn linux_execfn() -> &'static ZStr { +pub(crate) fn linux_execfn() -> &'static CStr { if let Some(libc_getauxval) = getauxval.get() { - unsafe { ZStr::from_ptr(libc_getauxval(c::AT_EXECFN).cast()) } + unsafe { CStr::from_ptr(libc_getauxval(c::AT_EXECFN).cast()) } } else { - zstr!("") + cstr!("") } } diff --git a/src/imp/libc/process/syscalls.rs b/src/imp/libc/process/syscalls.rs index b88c6ba3f..41a4ce1e4 100644 --- a/src/imp/libc/process/syscalls.rs +++ b/src/imp/libc/process/syscalls.rs @@ -15,7 +15,7 @@ use super::super::conv::{syscall_ret, syscall_ret_u32}; use super::types::RawCpuSet; #[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] use crate::fd::BorrowedFd; -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::io; use core::mem::MaybeUninit; #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] @@ -37,7 +37,7 @@ use { }; #[cfg(not(target_os = "wasi"))] -pub(crate) fn chdir(path: &ZStr) -> io::Result<()> { +pub(crate) fn chdir(path: &CStr) -> io::Result<()> { unsafe { ret(c::chdir(c_str(path))) } } diff --git a/src/imp/libc/termios/syscalls.rs b/src/imp/libc/termios/syscalls.rs index 1fb78d553..6c76a62fb 100644 --- a/src/imp/libc/termios/syscalls.rs +++ b/src/imp/libc/termios/syscalls.rs @@ -11,7 +11,7 @@ use super::super::conv::{borrowed_fd, ret, ret_pid_t}; use crate::fd::BorrowedFd; #[cfg(feature = "procfs")] #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::io; use crate::process::{Pid, RawNonZeroPid}; use crate::termios::{Action, OptionalActions, QueueSelector, Speed, Termios, Winsize}; @@ -155,6 +155,6 @@ pub(crate) fn ttyname(dirfd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result Weak { } unsafe fn fetch(name: &str) -> *mut c_void { - let name = match ZStr::from_bytes_with_nul(name.as_bytes()) { + let name = match CStr::from_bytes_with_nul(name.as_bytes()) { Ok(c_str) => c_str, Err(..) => return null_mut(), }; diff --git a/src/imp/linux_raw/conv.rs b/src/imp/linux_raw/conv.rs index f319b711f..6aab72655 100644 --- a/src/imp/linux_raw/conv.rs +++ b/src/imp/linux_raw/conv.rs @@ -30,7 +30,7 @@ use super::reg::{raw_arg, ArgNumber, ArgReg, RetReg, R0}; use super::time::types::ClockId; #[cfg(feature = "time")] use super::time::types::TimerfdClockId; -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::fs::{FileType, Mode, OFlags}; use crate::io::{self, OwnedFd}; use crate::process::{Pid, Resource, Signal}; @@ -115,17 +115,17 @@ impl<'a, Num: ArgNumber, T> From<*const T> for ArgReg<'a, Num> { } } -impl<'a, Num: ArgNumber> From<&'a ZStr> for ArgReg<'a, Num> { +impl<'a, Num: ArgNumber> From<&'a CStr> for ArgReg<'a, Num> { #[inline] - fn from(c: &'a ZStr) -> Self { + fn from(c: &'a CStr) -> Self { let mut_ptr = c.as_ptr() as *mut u8; raw_arg(mut_ptr.cast()) } } -impl<'a, Num: ArgNumber> From> for ArgReg<'a, Num> { +impl<'a, Num: ArgNumber> From> for ArgReg<'a, Num> { #[inline] - fn from(t: Option<&'a ZStr>) -> Self { + fn from(t: Option<&'a CStr>) -> Self { raw_arg(match t { Some(s) => { let mut_ptr = s.as_ptr() as *mut u8; diff --git a/src/imp/linux_raw/fs/dir.rs b/src/imp/linux_raw/fs/dir.rs index 28b91b37e..b4a380b82 100644 --- a/src/imp/linux_raw/fs/dir.rs +++ b/src/imp/linux_raw/fs/dir.rs @@ -1,5 +1,5 @@ use crate::fd::{AsFd, BorrowedFd}; -use crate::ffi::{ZStr, ZString}; +use crate::ffi::{CStr, CString}; use crate::fs::{fcntl_getfl, fstat, fstatfs, openat, FileType, Mode, OFlags, Stat, StatFs}; use crate::io::{self, OwnedFd}; use crate::process::fchdir; @@ -31,7 +31,7 @@ impl Dir { #[inline] fn _read_from(fd: BorrowedFd<'_>) -> io::Result { let flags = fcntl_getfl(fd)?; - let fd_for_dir = openat(fd, zstr!("."), flags | OFlags::CLOEXEC, Mode::empty())?; + let fd_for_dir = openat(fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty())?; Ok(Self { fd: fd_for_dir, @@ -96,14 +96,14 @@ impl Dir { // Read the NUL-terminated name from the `d_name` field. Without // `unsafe`, we need to scan for the NUL twice: once to obtain a size - // for the slice, and then once within `ZStr::from_bytes_with_nul`. + // for the slice, and then once within `CStr::from_bytes_with_nul`. let name_start = pos + offsetof_d_name; let name_len = self.buf[name_start..] .iter() .position(|x| *x == b'\0') .unwrap(); let name = - ZStr::from_bytes_with_nul(&self.buf[name_start..name_start + name_len + 1]).unwrap(); + CStr::from_bytes_with_nul(&self.buf[name_start..name_start + name_len + 1]).unwrap(); let name = name.to_owned(); assert!(name.as_bytes().len() <= self.buf.len() - name_start); @@ -193,13 +193,13 @@ impl fmt::Debug for Dir { pub struct DirEntry { d_ino: u64, d_type: u8, - name: ZString, + name: CString, } impl DirEntry { /// Returns the file name of this directory entry. #[inline] - pub fn file_name(&self) -> &ZStr { + pub fn file_name(&self) -> &CStr { &self.name } diff --git a/src/imp/linux_raw/fs/syscalls.rs b/src/imp/linux_raw/fs/syscalls.rs index e3749f8e5..525f32634 100644 --- a/src/imp/linux_raw/fs/syscalls.rs +++ b/src/imp/linux_raw/fs/syscalls.rs @@ -27,7 +27,7 @@ use super::super::conv::{loff_t, loff_t_from_u64, ret_u64}; ))] use crate::fd::AsFd; use crate::fd::{BorrowedFd, RawFd}; -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::fs::{ Access, Advice, AtFlags, FallocateFlags, FdFlags, FileType, FlockOperation, MemfdFlags, Mode, OFlags, RenameFlags, ResolveFlags, SealFlags, Stat, StatFs, StatxFlags, Timestamps, @@ -53,7 +53,7 @@ use { }; #[inline] -pub(crate) fn open(filename: &ZStr, flags: OFlags, mode: Mode) -> io::Result { +pub(crate) fn open(filename: &CStr, flags: OFlags, mode: Mode) -> io::Result { #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] { openat(crate::fs::cwd().as_fd(), filename, flags, mode) @@ -77,7 +77,7 @@ pub(crate) fn open(filename: &ZStr, flags: OFlags, mode: Mode) -> io::Result, - filename: &ZStr, + filename: &CStr, flags: OFlags, mode: Mode, ) -> io::Result { @@ -94,7 +94,7 @@ pub(crate) fn openat( #[inline] pub(crate) fn openat2( dirfd: BorrowedFd<'_>, - pathname: &ZStr, + pathname: &CStr, flags: OFlags, mode: Mode, resolve: ResolveFlags, @@ -130,7 +130,7 @@ pub(crate) fn openat2( } #[inline] -pub(crate) fn chmod(filename: &ZStr, mode: Mode) -> io::Result<()> { +pub(crate) fn chmod(filename: &CStr, mode: Mode) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_fchmodat, @@ -142,7 +142,7 @@ pub(crate) fn chmod(filename: &ZStr, mode: Mode) -> io::Result<()> { } #[inline] -pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, filename: &ZStr, mode: Mode) -> io::Result<()> { +pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, filename: &CStr, mode: Mode) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_fchmodat, dirfd, filename, mode)) } } @@ -154,7 +154,7 @@ pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { #[inline] pub(crate) fn chownat( dirfd: BorrowedFd<'_>, - filename: &ZStr, + filename: &CStr, owner: Uid, group: Gid, flags: AtFlags, @@ -186,7 +186,7 @@ pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Uid, group: Gid) -> io::Result<( #[inline] pub(crate) fn mknodat( dirfd: BorrowedFd<'_>, - filename: &ZStr, + filename: &CStr, file_type: FileType, mode: Mode, dev: u64, @@ -425,7 +425,7 @@ pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result { #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] { if !NO_STATX.load(Relaxed) { - match statx(fd, zstr!(""), AtFlags::EMPTY_PATH, StatxFlags::ALL) { + match statx(fd, cstr!(""), AtFlags::EMPTY_PATH, StatxFlags::ALL) { Ok(x) => return statx_to_stat(x), Err(io::Errno::NOSYS) => NO_STATX.store(true, Relaxed), Err(e) => return Err(e), @@ -459,7 +459,7 @@ fn fstat_old(fd: BorrowedFd<'_>) -> io::Result { } #[inline] -pub(crate) fn stat(filename: &ZStr) -> io::Result { +pub(crate) fn stat(filename: &CStr) -> io::Result { #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] { if !NO_STATX.load(Relaxed) { @@ -492,7 +492,7 @@ pub(crate) fn stat(filename: &ZStr) -> io::Result { } #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn stat_old(filename: &ZStr) -> io::Result { +fn stat_old(filename: &CStr) -> io::Result { let mut result = MaybeUninit::::uninit(); #[cfg(target_arch = "mips64")] @@ -521,7 +521,7 @@ fn stat_old(filename: &ZStr) -> io::Result { } #[inline] -pub(crate) fn statat(dirfd: BorrowedFd<'_>, filename: &ZStr, flags: AtFlags) -> io::Result { +pub(crate) fn statat(dirfd: BorrowedFd<'_>, filename: &CStr, flags: AtFlags) -> io::Result { #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] { if !NO_STATX.load(Relaxed) { @@ -549,7 +549,7 @@ pub(crate) fn statat(dirfd: BorrowedFd<'_>, filename: &ZStr, flags: AtFlags) -> } #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn statat_old(dirfd: BorrowedFd<'_>, filename: &ZStr, flags: AtFlags) -> io::Result { +fn statat_old(dirfd: BorrowedFd<'_>, filename: &CStr, flags: AtFlags) -> io::Result { let mut result = MaybeUninit::::uninit(); #[cfg(target_arch = "mips64")] @@ -578,7 +578,7 @@ fn statat_old(dirfd: BorrowedFd<'_>, filename: &ZStr, flags: AtFlags) -> io::Res } #[inline] -pub(crate) fn lstat(filename: &ZStr) -> io::Result { +pub(crate) fn lstat(filename: &CStr) -> io::Result { #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] { if !NO_STATX.load(Relaxed) { @@ -611,7 +611,7 @@ pub(crate) fn lstat(filename: &ZStr) -> io::Result { } #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn lstat_old(filename: &ZStr) -> io::Result { +fn lstat_old(filename: &CStr) -> io::Result { let mut result = MaybeUninit::::uninit(); #[cfg(target_arch = "mips64")] @@ -741,7 +741,7 @@ fn stat_to_stat(s: linux_raw_sys::general::stat) -> io::Result { #[inline] pub(crate) fn statx( dirfd: BorrowedFd<'_>, - pathname: &ZStr, + pathname: &CStr, flags: AtFlags, mask: StatxFlags, ) -> io::Result { @@ -781,7 +781,7 @@ pub(crate) fn fstatfs(fd: BorrowedFd<'_>) -> io::Result { } #[inline] -pub(crate) fn statfs(filename: &ZStr) -> io::Result { +pub(crate) fn statfs(filename: &CStr) -> io::Result { #[cfg(target_pointer_width = "32")] unsafe { let mut result = MaybeUninit::::uninit(); @@ -801,7 +801,7 @@ pub(crate) fn statfs(filename: &ZStr) -> io::Result { } #[inline] -pub(crate) fn readlink(path: &ZStr, buf: &mut [u8]) -> io::Result { +pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result { let (buf_addr_mut, buf_len) = slice_mut(buf); unsafe { ret_usize(syscall!( @@ -815,7 +815,7 @@ pub(crate) fn readlink(path: &ZStr, buf: &mut [u8]) -> io::Result { } #[inline] -pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &ZStr, buf: &mut [u8]) -> io::Result { +pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, buf: &mut [u8]) -> io::Result { let (buf_addr_mut, buf_len) = slice_mut(buf); unsafe { ret_usize(syscall!( @@ -1031,7 +1031,7 @@ pub(crate) fn fcntl_add_seals(fd: BorrowedFd<'_>, seals: SealFlags) -> io::Resul } #[inline] -pub(crate) fn rename(oldname: &ZStr, newname: &ZStr) -> io::Result<()> { +pub(crate) fn rename(oldname: &CStr, newname: &CStr) -> io::Result<()> { #[cfg(target_arch = "riscv64")] unsafe { ret(syscall_readonly!( @@ -1058,9 +1058,9 @@ pub(crate) fn rename(oldname: &ZStr, newname: &ZStr) -> io::Result<()> { #[inline] pub(crate) fn renameat( old_dirfd: BorrowedFd<'_>, - oldname: &ZStr, + oldname: &CStr, new_dirfd: BorrowedFd<'_>, - newname: &ZStr, + newname: &CStr, ) -> io::Result<()> { #[cfg(target_arch = "riscv64")] unsafe { @@ -1088,9 +1088,9 @@ pub(crate) fn renameat( #[inline] pub(crate) fn renameat2( old_dirfd: BorrowedFd<'_>, - oldname: &ZStr, + oldname: &CStr, new_dirfd: BorrowedFd<'_>, - newname: &ZStr, + newname: &CStr, flags: RenameFlags, ) -> io::Result<()> { unsafe { @@ -1106,7 +1106,7 @@ pub(crate) fn renameat2( } #[inline] -pub(crate) fn unlink(pathname: &ZStr) -> io::Result<()> { +pub(crate) fn unlink(pathname: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_unlinkat, @@ -1118,12 +1118,12 @@ pub(crate) fn unlink(pathname: &ZStr) -> io::Result<()> { } #[inline] -pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, pathname: &ZStr, flags: AtFlags) -> io::Result<()> { +pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, pathname: &CStr, flags: AtFlags) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_unlinkat, dirfd, pathname, flags)) } } #[inline] -pub(crate) fn rmdir(pathname: &ZStr) -> io::Result<()> { +pub(crate) fn rmdir(pathname: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_unlinkat, @@ -1135,7 +1135,7 @@ pub(crate) fn rmdir(pathname: &ZStr) -> io::Result<()> { } #[inline] -pub(crate) fn link(oldname: &ZStr, newname: &ZStr) -> io::Result<()> { +pub(crate) fn link(oldname: &CStr, newname: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_linkat, @@ -1151,9 +1151,9 @@ pub(crate) fn link(oldname: &ZStr, newname: &ZStr) -> io::Result<()> { #[inline] pub(crate) fn linkat( old_dirfd: BorrowedFd<'_>, - oldname: &ZStr, + oldname: &CStr, new_dirfd: BorrowedFd<'_>, - newname: &ZStr, + newname: &CStr, flags: AtFlags, ) -> io::Result<()> { unsafe { @@ -1169,7 +1169,7 @@ pub(crate) fn linkat( } #[inline] -pub(crate) fn symlink(oldname: &ZStr, newname: &ZStr) -> io::Result<()> { +pub(crate) fn symlink(oldname: &CStr, newname: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_symlinkat, @@ -1181,12 +1181,12 @@ pub(crate) fn symlink(oldname: &ZStr, newname: &ZStr) -> io::Result<()> { } #[inline] -pub(crate) fn symlinkat(oldname: &ZStr, dirfd: BorrowedFd<'_>, newname: &ZStr) -> io::Result<()> { +pub(crate) fn symlinkat(oldname: &CStr, dirfd: BorrowedFd<'_>, newname: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_symlinkat, oldname, dirfd, newname)) } } #[inline] -pub(crate) fn mkdir(pathname: &ZStr, mode: Mode) -> io::Result<()> { +pub(crate) fn mkdir(pathname: &CStr, mode: Mode) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_mkdirat, @@ -1198,7 +1198,7 @@ pub(crate) fn mkdir(pathname: &ZStr, mode: Mode) -> io::Result<()> { } #[inline] -pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, pathname: &ZStr, mode: Mode) -> io::Result<()> { +pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, pathname: &CStr, mode: Mode) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_mkdirat, dirfd, pathname, mode)) } } @@ -1212,7 +1212,7 @@ pub(crate) fn getdents(fd: BorrowedFd<'_>, dirent: &mut [u8]) -> io::Result, - pathname: &ZStr, + pathname: &CStr, times: &Timestamps, flags: AtFlags, ) -> io::Result<()> { @@ -1222,7 +1222,7 @@ pub(crate) fn utimensat( #[inline] fn _utimensat( dirfd: BorrowedFd<'_>, - pathname: Option<&ZStr>, + pathname: Option<&CStr>, times: &Timestamps, flags: AtFlags, ) -> io::Result<()> { @@ -1257,7 +1257,7 @@ fn _utimensat( #[cfg(target_pointer_width = "32")] unsafe fn _utimensat_old( dirfd: BorrowedFd<'_>, - pathname: Option<&ZStr>, + pathname: Option<&CStr>, times: &Timestamps, flags: AtFlags, ) -> io::Result<()> { @@ -1307,7 +1307,7 @@ pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> pub(crate) fn accessat( dirfd: BorrowedFd<'_>, - path: &ZStr, + path: &CStr, access: Access, flags: AtFlags, ) -> io::Result<()> { @@ -1364,7 +1364,7 @@ fn _copy_file_range( } #[inline] -pub(crate) fn memfd_create(name: &ZStr, flags: MemfdFlags) -> io::Result { +pub(crate) fn memfd_create(name: &CStr, flags: MemfdFlags) -> io::Result { unsafe { ret_owned_fd(syscall_readonly!(__NR_memfd_create, name, flags)) } } diff --git a/src/imp/linux_raw/net/addr.rs b/src/imp/linux_raw/net/addr.rs index 239c1860f..872c01c83 100644 --- a/src/imp/linux_raw/net/addr.rs +++ b/src/imp/linux_raw/net/addr.rs @@ -6,7 +6,7 @@ #![allow(unsafe_code)] use super::super::c; -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::{io, path}; use core::convert::TryInto; use core::{fmt, slice}; @@ -23,11 +23,11 @@ impl SocketAddrUnix { /// Construct a new Unix-domain address from a filesystem path. #[inline] pub fn new(path: P) -> io::Result { - path.into_with_z_str(Self::_new) + path.into_with_c_str(Self::_new) } #[inline] - fn _new(path: &ZStr) -> io::Result { + fn _new(path: &CStr) -> io::Result { let mut unix = Self::init(); let bytes = path.to_bytes_with_nul(); if bytes.len() > unix.sun_path.len() { @@ -66,7 +66,7 @@ impl SocketAddrUnix { /// For a filesystem path address, return the path. #[inline] - pub fn path(&self) -> Option<&ZStr> { + pub fn path(&self) -> Option<&CStr> { let len = self.len(); if len != 0 && self.unix.sun_path[0] != b'\0' as c::c_char { let end = len as usize - offsetof_sun_path(); @@ -74,7 +74,7 @@ impl SocketAddrUnix { // Safety: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. And // `from_bytes_with_nul_unchecked` since the string is NUL-terminated. unsafe { - Some(ZStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( + Some(CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( bytes.as_ptr().cast(), bytes.len(), ))) diff --git a/src/imp/linux_raw/process/auxv.rs b/src/imp/linux_raw/process/auxv.rs index d38073a06..ebec00394 100644 --- a/src/imp/linux_raw/process/auxv.rs +++ b/src/imp/linux_raw/process/auxv.rs @@ -8,7 +8,7 @@ use super::super::c; use super::super::elf::{Elf_Ehdr, Elf_Phdr}; #[cfg(feature = "process")] -use crate::ffi::ZStr; +use crate::ffi::CStr; use core::mem::size_of; use core::ptr::null; #[cfg(feature = "runtime")] @@ -39,12 +39,12 @@ pub(crate) fn linux_hwcap() -> (usize, usize) { #[cfg(feature = "process")] #[inline] -pub(crate) fn linux_execfn() -> &'static ZStr { +pub(crate) fn linux_execfn() -> &'static CStr { let execfn = auxv().execfn; // Safety: We assume the `AT_EXECFN` value provided by the kernel is a // valid pointer to a valid NUL-terminated array of bytes. - unsafe { ZStr::from_ptr(execfn.cast()) } + unsafe { CStr::from_ptr(execfn.cast()) } } #[cfg(feature = "runtime")] diff --git a/src/imp/linux_raw/process/syscalls.rs b/src/imp/linux_raw/process/syscalls.rs index 666a27168..37412a7d3 100644 --- a/src/imp/linux_raw/process/syscalls.rs +++ b/src/imp/linux_raw/process/syscalls.rs @@ -13,7 +13,7 @@ use super::super::conv::{ }; use super::types::{RawCpuSet, RawUname}; use crate::fd::BorrowedFd; -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::io; use crate::process::{ Cpuid, Gid, MembarrierCommand, MembarrierQuery, Pid, RawNonZeroPid, RawPid, Resource, Rlimit, @@ -25,7 +25,7 @@ use core::ptr::{null, null_mut}; use linux_raw_sys::general::{__kernel_gid_t, __kernel_pid_t, __kernel_uid_t}; #[inline] -pub(crate) fn chdir(filename: &ZStr) -> io::Result<()> { +pub(crate) fn chdir(filename: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_chdir, filename)) } } diff --git a/src/imp/linux_raw/runtime/syscalls.rs b/src/imp/linux_raw/runtime/syscalls.rs index 6e3a81f76..3c7ac90a9 100644 --- a/src/imp/linux_raw/runtime/syscalls.rs +++ b/src/imp/linux_raw/runtime/syscalls.rs @@ -10,7 +10,7 @@ use super::super::c; use super::super::conv::by_mut; use super::super::conv::{c_int, c_uint, ret, ret_c_uint, ret_error, ret_usize_infallible, zero}; use crate::fd::BorrowedFd; -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::fs::AtFlags; use crate::io; use crate::process::{Pid, RawNonZeroPid}; @@ -33,7 +33,7 @@ pub(crate) unsafe fn fork() -> io::Result> { pub(crate) unsafe fn execveat( dirfd: BorrowedFd<'_>, - path: &ZStr, + path: &CStr, args: *const *const u8, env_vars: *const *const u8, flags: AtFlags, @@ -49,7 +49,7 @@ pub(crate) unsafe fn execveat( } pub(crate) unsafe fn execve( - path: &ZStr, + path: &CStr, args: *const *const u8, env_vars: *const *const u8, ) -> io::Errno { @@ -92,7 +92,7 @@ pub(crate) mod tls { } #[inline] - pub(crate) unsafe fn set_thread_name(name: &ZStr) -> io::Result<()> { + pub(crate) unsafe fn set_thread_name(name: &CStr) -> io::Result<()> { ret(syscall_readonly!(__NR_prctl, c_uint(PR_SET_NAME), name)) } diff --git a/src/imp/linux_raw/termios/syscalls.rs b/src/imp/linux_raw/termios/syscalls.rs index e3d2effbe..aeae6ff67 100644 --- a/src/imp/linux_raw/termios/syscalls.rs +++ b/src/imp/linux_raw/termios/syscalls.rs @@ -15,7 +15,7 @@ use crate::termios::{ VMIN, VTIME, }; #[cfg(feature = "procfs")] -use crate::{ffi::ZStr, fs::FileType, path::DecInt}; +use crate::{ffi::CStr, fs::FileType, path::DecInt}; use core::mem::MaybeUninit; use linux_raw_sys::general::__kernel_pid_t; use linux_raw_sys::ioctl::{ @@ -226,7 +226,7 @@ pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result { // Gather the ttyname by reading the 'fd' file inside 'proc_self_fd'. let r = - super::super::fs::syscalls::readlinkat(proc_self_fd, DecInt::from_fd(&fd).as_z_str(), buf)?; + super::super::fs::syscalls::readlinkat(proc_self_fd, DecInt::from_fd(&fd).as_c_str(), buf)?; // If the number of bytes is equal to the buffer length, truncation may // have occurred. This check also ensures that we have enough space for @@ -237,7 +237,7 @@ pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result { buf[r] = b'\0'; // Check that the path we read refers to the same file as `fd`. - let path = ZStr::from_bytes_with_nul(&buf[..=r]).unwrap(); + let path = CStr::from_bytes_with_nul(&buf[..=r]).unwrap(); let path_stat = super::super::fs::syscalls::stat(path)?; if path_stat.st_dev != fd_stat.st_dev || path_stat.st_ino != fd_stat.st_ino { diff --git a/src/imp/linux_raw/vdso.rs b/src/imp/linux_raw/vdso.rs index 5ca0d17ae..d9d0f6426 100644 --- a/src/imp/linux_raw/vdso.rs +++ b/src/imp/linux_raw/vdso.rs @@ -16,7 +16,7 @@ use super::c; use super::elf::*; use super::mm::syscalls::madvise; use super::mm::types::Advice; -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::io; use core::ffi::c_void; use core::mem::{align_of, size_of}; @@ -42,7 +42,7 @@ pub(super) struct Vdso { } // Straight from the ELF specification. -fn elf_hash(name: &ZStr) -> u32 { +fn elf_hash(name: &CStr) -> u32 { let mut h: u32 = 0; for b in name.to_bytes() { h = (h << 4).wrapping_add(u32::from(*b)); @@ -303,7 +303,7 @@ impl Vdso { /// # Safety /// /// The raw pointers inside `self` must be valid. - unsafe fn match_version(&self, mut ver: u16, name: &ZStr, hash: u32) -> bool { + unsafe fn match_version(&self, mut ver: u16, name: &CStr, hash: u32) -> bool { // This is a helper function to check if the version indexed by // ver matches name (which hashes to hash). // @@ -344,11 +344,11 @@ impl Vdso { .add((*def).vd_aux as usize) .cast::(); (*def).vd_hash == hash - && (name == ZStr::from_ptr(self.symstrings.add(aux.vda_name as usize).cast())) + && (name == CStr::from_ptr(self.symstrings.add(aux.vda_name as usize).cast())) } /// Look up a symbol in the vDSO. - pub(super) fn sym(&self, version: &ZStr, name: &ZStr) -> *mut c::c_void { + pub(super) fn sym(&self, version: &CStr, name: &CStr) -> *mut c::c_void { let ver_hash = elf_hash(version); let name_hash = elf_hash(name); @@ -371,7 +371,7 @@ impl Vdso { || sym.st_shndx == SHN_UNDEF || sym.st_shndx == SHN_ABS || ELF_ST_VISIBILITY(sym.st_other) != STV_DEFAULT - || (name != ZStr::from_ptr(self.symstrings.add(sym.st_name as usize).cast())) + || (name != CStr::from_ptr(self.symstrings.add(sym.st_name as usize).cast())) // Check symbol version. || (!self.versym.is_null() && !self.match_version(*self.versym.add(chain as usize), version, ver_hash)) diff --git a/src/imp/linux_raw/vdso_wrappers.rs b/src/imp/linux_raw/vdso_wrappers.rs index 64c83d7ae..80c8dbefd 100644 --- a/src/imp/linux_raw/vdso_wrappers.rs +++ b/src/imp/linux_raw/vdso_wrappers.rs @@ -344,21 +344,21 @@ fn init() { // // [here]: https://man7.org/linux/man-pages/man7/vdso.7.html #[cfg(target_arch = "x86_64")] - let ptr = vdso.sym(zstr!("LINUX_2.6"), zstr!("__vdso_clock_gettime")); + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); #[cfg(target_arch = "arm")] - let ptr = vdso.sym(zstr!("LINUX_2.6"), zstr!("__vdso_clock_gettime64")); + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); #[cfg(target_arch = "aarch64")] - let ptr = vdso.sym(zstr!("LINUX_2.6.39"), zstr!("__kernel_clock_gettime")); + let ptr = vdso.sym(cstr!("LINUX_2.6.39"), cstr!("__kernel_clock_gettime")); #[cfg(target_arch = "x86")] - let ptr = vdso.sym(zstr!("LINUX_2.6"), zstr!("__vdso_clock_gettime64")); + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); #[cfg(target_arch = "riscv64")] - let ptr = vdso.sym(zstr!("LINUX_4.15"), zstr!("__vdso_clock_gettime")); + let ptr = vdso.sym(cstr!("LINUX_4.15"), cstr!("__vdso_clock_gettime")); #[cfg(target_arch = "powerpc64")] - let ptr = vdso.sym(zstr!("LINUX_2.6.15"), zstr!("__kernel_clock_gettime")); + let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_clock_gettime")); #[cfg(target_arch = "mips")] - let ptr = vdso.sym(zstr!("LINUX_2.6"), zstr!("__vdso_clock_gettime64")); + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); #[cfg(target_arch = "mips64")] - let ptr = vdso.sym(zstr!("LINUX_2.6"), zstr!("__vdso_clock_gettime")); + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); // On all 64-bit platforms, the 64-bit `clock_gettime` symbols are // always available. @@ -384,7 +384,7 @@ fn init() { // On x86, also look up the vsyscall entry point. #[cfg(target_arch = "x86")] { - let ptr = vdso.sym(zstr!("LINUX_2.5"), zstr!("__kernel_vsyscall")); + let ptr = vdso.sym(cstr!("LINUX_2.5"), cstr!("__kernel_vsyscall")); assert!(!ptr.is_null()); // Safety: As above, store the computed function addresses in diff --git a/src/io/procfs.rs b/src/io/procfs.rs index 1fdea50f7..4cc849878 100644 --- a/src/io/procfs.rs +++ b/src/io/procfs.rs @@ -17,7 +17,7 @@ //! to succeed with bogus results. use crate::fd::{AsFd, BorrowedFd}; -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::fs::{ cwd, fstat, fstatfs, major, openat, renameat, Dir, FileType, Mode, OFlags, Stat, PROC_SUPER_MAGIC, @@ -199,7 +199,7 @@ fn check_procfs(file: BorrowedFd<'_>) -> io::Result<()> { /// `renameat` call that would otherwise fail, but which fails with `EXDEV` /// first if it would cross a mount point. fn is_mountpoint(file: BorrowedFd<'_>) -> bool { - let err = renameat(file, zstr!("../."), file, zstr!(".")).unwrap_err(); + let err = renameat(file, cstr!("../."), file, cstr!(".")).unwrap_err(); match err { io::Errno::XDEV => true, // the rename failed due to crossing a mount point io::Errno::BUSY => false, // the rename failed normally @@ -231,7 +231,7 @@ fn proc() -> io::Result<(BorrowedFd<'static>, &'static Stat)> { // has no side effects. PROC.get_or_try_init(|| { // Open "/proc". - let proc = proc_opendirat(cwd(), zstr!("/proc"))?; + let proc = proc_opendirat(cwd(), cstr!("/proc"))?; let proc_stat = check_proc_entry( Kind::Proc, proc.as_fd(), @@ -303,7 +303,7 @@ pub fn proc_self_fd() -> io::Result> { let (proc_self, proc_self_stat) = proc_self()?; // Open "/proc/self/fd". - let proc_self_fd = proc_opendirat(proc_self, zstr!("fd"))?; + let proc_self_fd = proc_opendirat(proc_self, cstr!("fd"))?; let proc_self_fd_stat = check_proc_entry( Kind::Fd, proc_self_fd.as_fd(), @@ -345,7 +345,7 @@ fn proc_self_fdinfo() -> io::Result<(BorrowedFd<'static>, &'static Stat)> { let (proc_self, proc_self_stat) = proc_self()?; // Open "/proc/self/fdinfo". - let proc_self_fdinfo = proc_opendirat(proc_self, zstr!("fdinfo"))?; + let proc_self_fdinfo = proc_opendirat(proc_self, cstr!("fdinfo"))?; let proc_self_fdinfo_stat = check_proc_entry( Kind::Fd, proc_self_fdinfo.as_fd(), @@ -378,7 +378,7 @@ pub fn proc_self_fdinfo_fd(fd: Fd) -> io::Result { fn _proc_self_fdinfo(fd: BorrowedFd<'_>) -> io::Result { let (proc_self_fdinfo, proc_self_fdinfo_stat) = proc_self_fdinfo()?; let fd_str = DecInt::from_fd(fd); - open_and_check_file(proc_self_fdinfo, proc_self_fdinfo_stat, fd_str.as_z_str()) + open_and_check_file(proc_self_fdinfo, proc_self_fdinfo_stat, fd_str.as_c_str()) } /// Returns a handle to a Linux `/proc/self/pagemap` file. @@ -395,7 +395,7 @@ fn _proc_self_fdinfo(fd: BorrowedFd<'_>) -> io::Result { #[inline] #[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))] pub fn proc_self_pagemap() -> io::Result { - proc_self_file(zstr!("pagemap")) + proc_self_file(cstr!("pagemap")) } /// Returns a handle to a Linux `/proc/self/maps` file. @@ -410,17 +410,17 @@ pub fn proc_self_pagemap() -> io::Result { #[inline] #[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))] pub fn proc_self_maps() -> io::Result { - proc_self_file(zstr!("maps")) + proc_self_file(cstr!("maps")) } /// Open a file under `/proc/self`. -fn proc_self_file(name: &ZStr) -> io::Result { +fn proc_self_file(name: &CStr) -> io::Result { let (proc_self, proc_self_stat) = proc_self()?; open_and_check_file(proc_self, proc_self_stat, name) } /// Open a procfs file within in `dir` and check it for bind mounts. -fn open_and_check_file(dir: BorrowedFd, dir_stat: &Stat, name: &ZStr) -> io::Result { +fn open_and_check_file(dir: BorrowedFd, dir_stat: &Stat, name: &CStr) -> io::Result { let (_, proc_stat) = proc()?; let oflags = @@ -470,7 +470,7 @@ fn open_and_check_file(dir: BorrowedFd, dir_stat: &Stat, name: &ZStr) -> io::Res found_file = true; } else if entry.ino() == dir_stat.st_ino && entry.file_type() == FileType::Directory - && entry.file_name() == zstr!(".") + && entry.file_name() == cstr!(".") { // We found ".", and it's the right ".". found_dot = true; diff --git a/src/lib.rs b/src/lib.rs index 5cdc004e7..91d4c857d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,18 +102,10 @@ feature(naked_functions) )] #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] +#![cfg_attr(core_c_str, feature(core_c_str))] +#![cfg_attr(alloc_c_string, feature(alloc_ffi))] +#![cfg_attr(alloc_c_string, feature(alloc_c_string))] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(all(not(feature = "std"), specialization), allow(incomplete_features))] -#![cfg_attr(all(not(feature = "std"), specialization), feature(specialization))] -#![cfg_attr(all(not(feature = "std"), slice_internals), feature(slice_internals))] -#![cfg_attr( - all(not(feature = "std"), toowned_clone_into), - feature(toowned_clone_into) -)] -#![cfg_attr( - all(not(feature = "std"), vec_into_raw_parts), - feature(vec_into_raw_parts) -)] #![cfg_attr(feature = "rustc-dep-of-std", feature(core_intrinsics))] #![cfg_attr(feature = "rustc-dep-of-std", feature(ip))] #![cfg_attr( @@ -129,7 +121,7 @@ extern crate alloc; // Internal utilities. #[cfg(not(windows))] #[macro_use] -pub(crate) mod zstr; +pub(crate) mod cstr; #[macro_use] pub(crate) mod const_assert; pub(crate) mod utils; diff --git a/src/path/arg.rs b/src/path/arg.rs index 9faf046b4..187e9ab2c 100644 --- a/src/path/arg.rs +++ b/src/path/arg.rs @@ -5,7 +5,7 @@ //! to rustix APIs with string arguments, and it allows rustix to implement //! NUL-termination without the need for copying where possible. -use crate::ffi::{ZStr, ZString}; +use crate::ffi::{CStr, CString}; use crate::io; #[cfg(feature = "itoa")] use crate::path::DecInt; @@ -40,25 +40,25 @@ use std::path::{Component, Components, Iter, Path, PathBuf}; /// /// ```rust /// # #[cfg(any(feature = "fs", feature = "net"))] -/// use rustix::ffi::ZStr; +/// use rustix::ffi::CStr; /// use rustix::io; /// # #[cfg(any(feature = "fs", feature = "net"))] /// use rustix::path::Arg; /// /// # #[cfg(any(feature = "fs", feature = "net"))] /// pub fn touch(path: P) -> io::Result<()> { -/// let path = path.into_z_str()?; +/// let path = path.into_c_str()?; /// _touch(&path) /// } /// /// # #[cfg(any(feature = "fs", feature = "net"))] -/// fn _touch(path: &ZStr) -> io::Result<()> { +/// fn _touch(path: &CStr) -> io::Result<()> { /// // implementation goes here /// Ok(()) /// } /// ``` /// -/// Users can then call `touch("foo")`, `touch(zstr!("foo"))`, +/// Users can then call `touch("foo")`, `touch(cstr!("foo"))`, /// `touch(Path::new("foo"))`, or many other things. /// /// [`AsRef`]: std::convert::AsRef @@ -70,49 +70,20 @@ pub trait Arg { /// str>`. fn to_string_lossy(&self) -> Cow<'_, str>; - /// Returns a view of this string as a maybe-owned [`ZStr`]. - fn as_cow_z_str(&self) -> io::Result>; + /// Returns a view of this string as a maybe-owned [`CStr`]. + fn as_cow_c_str(&self) -> io::Result>; /// Consumes `self` and returns a view of this string as a maybe-owned - /// [`ZStr`]. - fn into_z_str<'b>(self) -> io::Result> + /// [`CStr`]. + fn into_c_str<'b>(self) -> io::Result> where Self: 'b; - /// Runs a closure with `self` passed in as a `&ZStr`. - fn into_with_z_str(self, f: F) -> io::Result - where - Self: Sized, - F: FnOnce(&ZStr) -> io::Result; - - /// Returns a view of this string as a maybe-owned [`ZStr`]. - #[cfg(not(feature = "rustc-dep-of-std"))] - #[inline] - fn as_cow_c_str(&self) -> io::Result> { - self.as_cow_z_str() - } - - /// Consumes `self` and returns a view of this string as a maybe-owned - /// [`ZStr`]. - #[cfg(not(feature = "rustc-dep-of-std"))] - #[inline] - fn into_c_str<'b>(self) -> io::Result> - where - Self: 'b + Sized, - { - self.into_z_str() - } - - /// Runs a closure with `self` passed in as a `&ZStr`. - #[cfg(not(feature = "rustc-dep-of-std"))] - #[inline] + /// Runs a closure with `self` passed in as a `&CStr`. fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, - { - self.into_with_z_str(f) - } + F: FnOnce(&CStr) -> io::Result; } impl Arg for &str { @@ -127,29 +98,29 @@ impl Arg for &str { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_bytes(), f) + with_c_str(self.as_bytes(), f) } } @@ -165,27 +136,27 @@ impl Arg for &String { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(String::as_str(self).as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(String::as_str(self).as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { - self.as_str().into_z_str() + self.as_str().into_c_str() } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_bytes(), f) + with_c_str(self.as_bytes(), f) } } @@ -201,29 +172,29 @@ impl Arg for String { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - f(&ZString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?) + f(&CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?) } } @@ -240,29 +211,29 @@ impl Arg for &OsStr { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_bytes(), f) + with_c_str(self.as_bytes(), f) } } @@ -279,28 +250,28 @@ impl Arg for &OsString { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(OsString::as_os_str(self).as_bytes()) + CString::new(OsString::as_os_str(self).as_bytes()) .map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { - self.as_os_str().into_z_str() + self.as_os_str().into_c_str() } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_bytes(), f) + with_c_str(self.as_bytes(), f) } } @@ -317,29 +288,29 @@ impl Arg for OsString { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self.into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - f(&ZString::new(self.into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?) + f(&CString::new(self.into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?) } } @@ -356,29 +327,29 @@ impl Arg for &Path { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_os_str().as_bytes(), f) + with_c_str(self.as_os_str().as_bytes(), f) } } @@ -398,28 +369,28 @@ impl Arg for &PathBuf { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(PathBuf::as_path(self).as_os_str().as_bytes()) + CString::new(PathBuf::as_path(self).as_os_str().as_bytes()) .map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { - self.as_path().into_z_str() + self.as_path().into_c_str() } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_os_str().as_bytes(), f) + with_c_str(self.as_os_str().as_bytes(), f) } } @@ -436,36 +407,36 @@ impl Arg for PathBuf { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self.into_os_string().into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.into_os_string().into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { f( - &ZString::new(self.into_os_string().into_vec()) + &CString::new(self.into_os_string().into_vec()) .map_err(|_cstr_err| io::Errno::INVAL)?, ) } } -impl Arg for &ZStr { +impl Arg for &CStr { #[inline] fn as_str(&self) -> io::Result<&str> { self.to_str().map_err(|_utf8_err| io::Errno::INVAL) @@ -473,16 +444,16 @@ impl Arg for &ZStr { #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { - ZStr::to_string_lossy(self) + CStr::to_string_lossy(self) } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Borrowed(self)) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { @@ -490,16 +461,16 @@ impl Arg for &ZStr { } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { f(self) } } -impl Arg for &ZString { +impl Arg for &CString { #[inline] fn as_str(&self) -> io::Result<&str> { unimplemented!() @@ -511,12 +482,12 @@ impl Arg for &ZString { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Borrowed(self)) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { @@ -524,16 +495,16 @@ impl Arg for &ZString { } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { f(self) } } -impl Arg for ZString { +impl Arg for CString { #[inline] fn as_str(&self) -> io::Result<&str> { self.to_str().map_err(|_utf8_err| io::Errno::INVAL) @@ -541,16 +512,16 @@ impl Arg for ZString { #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { - ZStr::to_string_lossy(self) + CStr::to_string_lossy(self) } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Borrowed(self)) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { @@ -558,10 +529,10 @@ impl Arg for ZString { } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { f(&self) } @@ -579,33 +550,33 @@ impl<'a> Arg for Cow<'a, str> { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_ref()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_ref()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( match self { - Cow::Owned(s) => ZString::new(s), - Cow::Borrowed(s) => ZString::new(s), + Cow::Owned(s) => CString::new(s), + Cow::Borrowed(s) => CString::new(s), } .map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_bytes(), f) + with_c_str(self.as_bytes(), f) } } @@ -622,37 +593,37 @@ impl<'a> Arg for Cow<'a, OsStr> { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( match self { - Cow::Owned(os) => ZString::new(os.into_vec()), - Cow::Borrowed(os) => ZString::new(os.as_bytes()), + Cow::Owned(os) => CString::new(os.into_vec()), + Cow::Borrowed(os) => CString::new(os.as_bytes()), } .map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_bytes(), f) + with_c_str(self.as_bytes(), f) } } -impl<'a> Arg for Cow<'a, ZStr> { +impl<'a> Arg for Cow<'a, CStr> { #[inline] fn as_str(&self) -> io::Result<&str> { self.to_str().map_err(|_utf8_err| io::Errno::INVAL) @@ -660,17 +631,17 @@ impl<'a> Arg for Cow<'a, ZStr> { #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { - let borrow: &ZStr = core::borrow::Borrow::borrow(self); + let borrow: &CStr = core::borrow::Borrow::borrow(self); borrow.to_string_lossy() } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Borrowed(self)) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { @@ -678,10 +649,10 @@ impl<'a> Arg for Cow<'a, ZStr> { } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { f(&self) } @@ -700,29 +671,29 @@ impl<'a> Arg for Component<'a> { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_os_str().as_bytes(), f) + with_c_str(self.as_os_str().as_bytes(), f) } } @@ -739,31 +710,31 @@ impl<'a> Arg for Components<'a> { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_path().as_os_str().as_bytes()) + CString::new(self.as_path().as_os_str().as_bytes()) .map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self.as_path().as_os_str().as_bytes()) + CString::new(self.as_path().as_os_str().as_bytes()) .map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_path().as_os_str().as_bytes(), f) + with_c_str(self.as_path().as_os_str().as_bytes(), f) } } @@ -780,31 +751,31 @@ impl<'a> Arg for Iter<'a> { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_path().as_os_str().as_bytes()) + CString::new(self.as_path().as_os_str().as_bytes()) .map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self.as_path().as_os_str().as_bytes()) + CString::new(self.as_path().as_os_str().as_bytes()) .map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self.as_path().as_os_str().as_bytes(), f) + with_c_str(self.as_path().as_os_str().as_bytes(), f) } } @@ -820,29 +791,29 @@ impl Arg for &[u8] { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(*self).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(*self).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self, f) + with_c_str(self, f) } } @@ -858,29 +829,29 @@ impl Arg for &Vec { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - with_z_str(self, f) + with_c_str(self, f) } } @@ -896,29 +867,29 @@ impl Arg for Vec { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - f(&ZString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?) + f(&CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?) } } @@ -935,37 +906,37 @@ impl Arg for DecInt { } #[inline] - fn as_cow_z_str(&self) -> io::Result> { + fn as_cow_c_str(&self) -> io::Result> { Ok(Cow::Owned( - ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_z_str<'b>(self) -> io::Result> + fn into_c_str<'b>(self) -> io::Result> where Self: 'b, { Ok(Cow::Owned( - ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, + CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, )) } #[inline] - fn into_with_z_str(self, f: F) -> io::Result + fn into_with_c_str(self, f: F) -> io::Result where Self: Sized, - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - f(self.as_z_str()) + f(self.as_c_str()) } } -/// Runs a closure with `bytes` passed in as a `&ZStr`. +/// Runs a closure with `bytes` passed in as a `&CStr`. #[inline] -fn with_z_str(bytes: &[u8], f: F) -> io::Result +fn with_c_str(bytes: &[u8], f: F) -> io::Result where - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { // Most paths are less than `SMALL_PATH_BUFFER_SIZE` long. The rest can go // through the dynamic allocation path. If you're opening many files in a @@ -975,20 +946,20 @@ where // Test with >= so that we have room for the trailing NUL. if bytes.len() >= SMALL_PATH_BUFFER_SIZE { - return with_z_str_slow_path(bytes, f); + return with_c_str_slow_path(bytes, f); } let mut buffer: [u8; SMALL_PATH_BUFFER_SIZE] = [0_u8; SMALL_PATH_BUFFER_SIZE]; // Copy the bytes in; the buffer already has zeros for the trailing NUL. buffer[..bytes.len()].copy_from_slice(bytes); - f(ZStr::from_bytes_with_nul(&buffer[..=bytes.len()]).map_err(|_cstr_err| io::Errno::INVAL)?) + f(CStr::from_bytes_with_nul(&buffer[..=bytes.len()]).map_err(|_cstr_err| io::Errno::INVAL)?) } /// The slow path which handles any length. In theory OS's only support up /// to `PATH_MAX`, but we let the OS enforce that. #[cold] -fn with_z_str_slow_path(bytes: &[u8], f: F) -> io::Result +fn with_c_str_slow_path(bytes: &[u8], f: F) -> io::Result where - F: FnOnce(&ZStr) -> io::Result, + F: FnOnce(&CStr) -> io::Result, { - f(&ZString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?) + f(&CString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?) } diff --git a/src/path/dec_int.rs b/src/path/dec_int.rs index fe62b5129..88083a567 100644 --- a/src/path/dec_int.rs +++ b/src/path/dec_int.rs @@ -6,14 +6,14 @@ //! `str::from_utf8_unchecked`on the buffer that it filled itself. #![allow(unsafe_code)] -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::imp::fd::{AsFd, AsRawFd}; #[cfg(feature = "std")] use core::fmt; use core::fmt::Write; use itoa::{Buffer, Integer}; #[cfg(feature = "std")] -use std::ffi::{CStr, OsStr}; +use std::ffi::OsStr; #[cfg(feature = "std")] #[cfg(unix)] use std::os::unix::ffi::OsStrExt; @@ -79,23 +79,12 @@ impl DecInt { unsafe { core::str::from_utf8_unchecked(self.as_bytes()) } } - /// Return the raw byte buffer as a `&ZStr`. - #[inline] - pub fn as_z_str(&self) -> &ZStr { - let bytes_with_nul = &self.buf[..=self.len]; - debug_assert!(ZStr::from_bytes_with_nul(bytes_with_nul).is_ok()); - - // Safety: `self.buf` holds a single decimal ASCII representation and - // at least one extra NUL byte. - unsafe { ZStr::from_bytes_with_nul_unchecked(bytes_with_nul) } - } - /// Return the raw byte buffer as a `&CStr`. - #[cfg(feature = "std")] #[inline] pub fn as_c_str(&self) -> &CStr { let bytes_with_nul = &self.buf[..=self.len]; debug_assert!(CStr::from_bytes_with_nul(bytes_with_nul).is_ok()); + // Safety: `self.buf` holds a single decimal ASCII representation and // at least one extra NUL byte. unsafe { CStr::from_bytes_with_nul_unchecked(bytes_with_nul) } diff --git a/src/process/auxv.rs b/src/process/auxv.rs index d70d33bfd..08d4567d1 100644 --- a/src/process/auxv.rs +++ b/src/process/auxv.rs @@ -16,7 +16,7 @@ ) ) ))] -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::imp; /// `sysconf(_SC_PAGESIZE)`—Returns the process' page size. @@ -99,7 +99,7 @@ pub fn linux_hwcap() -> (usize, usize) { ) ))] #[inline] -pub fn linux_execfn() -> &'static ZStr { +pub fn linux_execfn() -> &'static CStr { imp::process::auxv::linux_execfn() } diff --git a/src/process/chdir.rs b/src/process/chdir.rs index 07267d8ec..d8e251074 100644 --- a/src/process/chdir.rs +++ b/src/process/chdir.rs @@ -1,4 +1,4 @@ -use crate::ffi::ZString; +use crate::ffi::CString; use crate::path::SMALL_PATH_BUFFER_SIZE; use crate::{imp, io, path}; use alloc::vec::Vec; @@ -15,7 +15,7 @@ use imp::fd::AsFd; /// [Linux]: https://man7.org/linux/man-pages/man2/chdir.2.html #[inline] pub fn chdir(path: P) -> io::Result<()> { - path.into_with_z_str(imp::process::syscalls::chdir) + path.into_with_c_str(imp::process::syscalls::chdir) } /// `fchdir(fd)`—Change the current working directory. @@ -44,11 +44,11 @@ pub fn fchdir(fd: Fd) -> io::Result<()> { /// [Linux]: https://man7.org/linux/man-pages/man3/getcwd.3.html #[cfg(not(target_os = "wasi"))] #[inline] -pub fn getcwd>>(reuse: B) -> io::Result { +pub fn getcwd>>(reuse: B) -> io::Result { _getcwd(reuse.into()) } -fn _getcwd(mut buffer: Vec) -> io::Result { +fn _getcwd(mut buffer: Vec) -> io::Result { // This code would benefit from having a better way to read into // uninitialized memory, but that requires `unsafe`. buffer.clear(); @@ -64,7 +64,7 @@ fn _getcwd(mut buffer: Vec) -> io::Result { Ok(_) => { let len = buffer.iter().position(|x| *x == b'\0').unwrap(); buffer.resize(len, 0_u8); - return Ok(ZString::new(buffer).unwrap()); + return Ok(CString::new(buffer).unwrap()); } Err(errno) => return Err(errno), } diff --git a/src/process/uname.rs b/src/process/uname.rs index 3e92358b9..a17d0be7a 100644 --- a/src/process/uname.rs +++ b/src/process/uname.rs @@ -6,7 +6,7 @@ //! kernel into `&str` references, which assumes that they're NUL-terminated. #![allow(unsafe_code)] -use crate::ffi::ZStr; +use crate::ffi::CStr; use crate::imp; use core::fmt; @@ -24,7 +24,7 @@ pub struct Uname(imp::process::types::RawUname); impl Uname { /// `sysname`—Operating system release name #[inline] - pub fn sysname(&self) -> &ZStr { + pub fn sysname(&self) -> &CStr { Self::to_cstr(self.0.sysname.as_ptr().cast()) } @@ -34,39 +34,39 @@ impl Uname { /// information about hosts that have multiple names, or any information /// about where the names are visible. #[inline] - pub fn nodename(&self) -> &ZStr { + pub fn nodename(&self) -> &CStr { Self::to_cstr(self.0.nodename.as_ptr().cast()) } /// `release`—Operating system release version string #[inline] - pub fn release(&self) -> &ZStr { + pub fn release(&self) -> &CStr { Self::to_cstr(self.0.release.as_ptr().cast()) } /// `version`—Operating system build identifiers #[inline] - pub fn version(&self) -> &ZStr { + pub fn version(&self) -> &CStr { Self::to_cstr(self.0.version.as_ptr().cast()) } /// `machine`—Hardware architecture identifier #[inline] - pub fn machine(&self) -> &ZStr { + pub fn machine(&self) -> &CStr { Self::to_cstr(self.0.machine.as_ptr().cast()) } /// `domainname`—NIS or YP domain identifier #[cfg(any(target_os = "android", target_os = "linux"))] #[inline] - pub fn domainname(&self) -> &ZStr { + pub fn domainname(&self) -> &CStr { Self::to_cstr(self.0.domainname.as_ptr().cast()) } #[inline] - fn to_cstr<'a>(ptr: *const u8) -> &'a ZStr { + fn to_cstr<'a>(ptr: *const u8) -> &'a CStr { // Safety: Strings returned from the kernel are always NUL-terminated. - unsafe { ZStr::from_ptr(ptr.cast()) } + unsafe { CStr::from_ptr(ptr.cast()) } } } diff --git a/src/runtime.rs b/src/runtime.rs index 34d28f36a..7d10df49f 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -20,7 +20,7 @@ #![allow(unsafe_code)] #[cfg(linux_raw)] -use crate::ffi::ZStr; +use crate::ffi::CStr; #[cfg(linux_raw)] use crate::fs::AtFlags; use crate::imp; @@ -73,7 +73,7 @@ pub unsafe fn set_tid_address(data: *mut c_void) -> Pid { /// [Linux]: https://man7.org/linux/man-pages/man2/prctl.2.html #[cfg(linux_raw)] #[inline] -pub unsafe fn set_thread_name(name: &ZStr) -> io::Result<()> { +pub unsafe fn set_thread_name(name: &CStr) -> io::Result<()> { imp::runtime::syscalls::tls::set_thread_name(name) } @@ -222,7 +222,7 @@ pub unsafe fn fork() -> io::Result> { imp::runtime::syscalls::fork() } -/// `execveat(dirfd, path.as_z_str(), argv, envp, flags)`—Execute a new +/// `execveat(dirfd, path.as_c_str(), argv, envp, flags)`—Execute a new /// command using the current process. /// /// # Safety @@ -238,7 +238,7 @@ pub unsafe fn fork() -> io::Result> { #[cfg(linux_raw)] pub unsafe fn execveat( dirfd: Fd, - path: &ZStr, + path: &CStr, argv: *const *const u8, envp: *const *const u8, flags: AtFlags, @@ -246,7 +246,7 @@ pub unsafe fn execveat( imp::runtime::syscalls::execveat(dirfd.as_fd(), path, argv, envp, flags) } -/// `execve(path.as_z_str(), argv, envp)`—Execute a new command using the +/// `execve(path.as_c_str(), argv, envp)`—Execute a new command using the /// current process. /// /// # Safety @@ -260,6 +260,6 @@ pub unsafe fn execveat( /// [Linux]: https://man7.org/linux/man-pages/man2/execve.2.html #[inline] #[cfg(linux_raw)] -pub unsafe fn execve(path: &ZStr, argv: *const *const u8, envp: *const *const u8) -> io::Errno { +pub unsafe fn execve(path: &CStr, argv: *const *const u8, envp: *const *const u8) -> io::Errno { imp::runtime::syscalls::execve(path, argv, envp) } diff --git a/src/termios/tty.rs b/src/termios/tty.rs index 572e7e8a1..d28af2040 100644 --- a/src/termios/tty.rs +++ b/src/termios/tty.rs @@ -13,7 +13,7 @@ use imp::fd::AsFd; all(libc, not(any(target_os = "fuchsia", target_os = "wasi"))) ))] use { - crate::ffi::ZString, crate::path::SMALL_PATH_BUFFER_SIZE, alloc::vec::Vec, imp::fd::BorrowedFd, + crate::ffi::CString, crate::path::SMALL_PATH_BUFFER_SIZE, alloc::vec::Vec, imp::fd::BorrowedFd, }; /// `isatty(fd)`—Tests whether a file descriptor refers to a terminal. @@ -43,13 +43,13 @@ pub fn isatty(fd: Fd) -> bool { #[cfg(feature = "procfs")] #[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))] #[inline] -pub fn ttyname>>(dirfd: Fd, reuse: B) -> io::Result { +pub fn ttyname>>(dirfd: Fd, reuse: B) -> io::Result { _ttyname(dirfd.as_fd(), reuse.into()) } #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] #[cfg(feature = "procfs")] -fn _ttyname(dirfd: BorrowedFd<'_>, mut buffer: Vec) -> io::Result { +fn _ttyname(dirfd: BorrowedFd<'_>, mut buffer: Vec) -> io::Result { // This code would benefit from having a better way to read into // uninitialized memory, but that requires `unsafe`. buffer.clear(); @@ -64,7 +64,7 @@ fn _ttyname(dirfd: BorrowedFd<'_>, mut buffer: Vec) -> io::Result { } Ok(len) => { buffer.resize(len, 0_u8); - return Ok(ZString::new(buffer).unwrap()); + return Ok(CString::new(buffer).unwrap()); } Err(errno) => return Err(errno), } diff --git a/tests/fs/dir.rs b/tests/fs/dir.rs index 22da54d2d..f5120be96 100644 --- a/tests/fs/dir.rs +++ b/tests/fs/dir.rs @@ -2,7 +2,7 @@ fn test_dir() { let t = rustix::fs::openat( rustix::fs::cwd(), - rustix::zstr!("."), + rustix::cstr!("."), rustix::fs::OFlags::RDONLY | rustix::fs::OFlags::CLOEXEC, rustix::fs::Mode::empty(), ) @@ -12,7 +12,7 @@ fn test_dir() { let _file = rustix::fs::openat( &t, - rustix::zstr!("Cargo.toml"), + rustix::cstr!("Cargo.toml"), rustix::fs::OFlags::RDONLY | rustix::fs::OFlags::CLOEXEC, rustix::fs::Mode::empty(), ) @@ -23,11 +23,11 @@ fn test_dir() { let mut saw_cargo_toml = false; for entry in dir { let entry = entry.unwrap(); - if entry.file_name() == rustix::zstr!(".") { + if entry.file_name() == rustix::cstr!(".") { saw_dot = true; - } else if entry.file_name() == rustix::zstr!("..") { + } else if entry.file_name() == rustix::cstr!("..") { saw_dotdot = true; - } else if entry.file_name() == rustix::zstr!("Cargo.toml") { + } else if entry.file_name() == rustix::cstr!("Cargo.toml") { saw_cargo_toml = true; } } diff --git a/tests/fs/openat2.rs b/tests/fs/openat2.rs index aff3e2c4c..0b1d86fe2 100644 --- a/tests/fs/openat2.rs +++ b/tests/fs/openat2.rs @@ -12,7 +12,7 @@ fn openat2_more( mode: Mode, resolve: ResolveFlags, ) -> io::Result { - let path = path.as_cow_z_str().unwrap().into_owned(); + let path = path.as_cow_c_str().unwrap().into_owned(); loop { match openat2(dirfd.as_fd(), &path, oflags, mode, resolve) { Ok(file) => return Ok(file), diff --git a/tests/net/addr.rs b/tests/net/addr.rs index 220b4eea7..9b5accd51 100644 --- a/tests/net/addr.rs +++ b/tests/net/addr.rs @@ -33,24 +33,24 @@ fn encode_decode() { #[cfg(not(windows))] #[test] fn test_unix_addr() { + use rustix::cstr; use rustix::net::SocketAddrUnix; - use rustix::zstr; assert_eq!( SocketAddrUnix::new("/").unwrap().path().unwrap(), - zstr!("/") + cstr!("/") ); assert_eq!( SocketAddrUnix::new("//").unwrap().path().unwrap(), - zstr!("//") + cstr!("//") ); assert_eq!( SocketAddrUnix::new("/foo/bar").unwrap().path().unwrap(), - zstr!("/foo/bar") + cstr!("/foo/bar") ); assert_eq!( SocketAddrUnix::new("foo").unwrap().path().unwrap(), - zstr!("foo") + cstr!("foo") ); SocketAddrUnix::new("/foo\0/bar").unwrap_err(); assert!(SocketAddrUnix::new("").unwrap().path().is_none()); diff --git a/tests/path/arg.rs b/tests/path/arg.rs index 7427d6014..860829e12 100644 --- a/tests/path/arg.rs +++ b/tests/path/arg.rs @@ -1,4 +1,4 @@ -use rustix::ffi::{ZStr, ZString}; +use rustix::ffi::{CStr, CString}; use rustix::io; use rustix::path::Arg; #[cfg(feature = "itoa")] @@ -9,163 +9,163 @@ use std::path::{Component, Components, Iter, Path, PathBuf}; #[test] fn test_arg() { - use rustix::zstr; + use rustix::cstr; use std::borrow::Borrow; let t: &str = "hello"; assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.into_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); let t: String = "hello".to_owned(); assert_eq!("hello", Arg::as_str(&t).unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); let t: &OsStr = OsStr::new("hello"); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.into_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); let t: OsString = OsString::from("hello".to_owned()); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); let t: &Path = Path::new("hello"); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.into_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); let t: PathBuf = PathBuf::from("hello".to_owned()); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); - let t: &ZStr = zstr!("hello"); + let t: &CStr = cstr!("hello"); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.into_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - let t: ZString = zstr!("hello").to_owned(); + let t: CString = cstr!("hello").to_owned(); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); assert_eq!( - zstr!("hello"), - Borrow::borrow(&Arg::as_cow_z_str(&t).unwrap()) + cstr!("hello"), + Borrow::borrow(&Arg::as_cow_c_str(&t).unwrap()) ); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); let t: Components = Path::new("hello").components(); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); let t: Component = Path::new("hello").components().next().unwrap(); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.into_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); let t: Iter = Path::new("hello").iter(); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); let t: Cow<'_, str> = Cow::Borrowed("hello"); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); let t: Cow<'_, str> = Cow::Owned("hello".to_owned()); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); let t: Cow<'_, OsStr> = Cow::Borrowed(OsStr::new("hello")); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); let t: Cow<'_, OsStr> = Cow::Owned(OsString::from("hello".to_owned())); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); - let t: Cow<'_, ZStr> = Cow::Borrowed(zstr!("hello")); + let t: Cow<'_, CStr> = Cow::Borrowed(cstr!("hello")); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); - let t: Cow<'_, ZStr> = Cow::Owned(zstr!("hello").to_owned()); + let t: Cow<'_, CStr> = Cow::Owned(cstr!("hello").to_owned()); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); let t: &[u8] = b"hello"; assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.into_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); let t: Vec = b"hello".to_vec(); assert_eq!("hello", t.as_str().unwrap()); assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("hello"), Borrow::borrow(&t.as_cow_z_str().unwrap())); + assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); assert_eq!( - zstr!("hello"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("hello"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); #[cfg(feature = "itoa")] @@ -173,11 +173,11 @@ fn test_arg() { let t: DecInt = DecInt::new(43110); assert_eq!("43110", t.as_str()); assert_eq!("43110".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(zstr!("43110"), Borrow::borrow(&t.as_cow_z_str().unwrap())); - assert_eq!(zstr!("43110"), t.as_c_str()); + assert_eq!(cstr!("43110"), Borrow::borrow(&t.as_cow_c_str().unwrap())); + assert_eq!(cstr!("43110"), t.as_c_str()); assert_eq!( - zstr!("43110"), - Borrow::borrow(&t.clone().into_z_str().unwrap()) + cstr!("43110"), + Borrow::borrow(&t.clone().into_c_str().unwrap()) ); } } @@ -191,11 +191,11 @@ fn test_invalid() { assert_eq!("hello\u{fffd}world".to_owned(), Arg::to_string_lossy(&t)); assert_eq!( b"hello\xc0world\0", - Borrow::::borrow(&t.as_cow_z_str().unwrap()).to_bytes_with_nul() + Borrow::::borrow(&t.as_cow_c_str().unwrap()).to_bytes_with_nul() ); assert_eq!( b"hello\xc0world\0", - Borrow::::borrow(&t.clone().into_z_str().unwrap()).to_bytes_with_nul() + Borrow::::borrow(&t.clone().into_c_str().unwrap()).to_bytes_with_nul() ); } @@ -204,6 +204,6 @@ fn test_embedded_nul() { let t: &[u8] = b"hello\0world"; assert_eq!("hello\0world", t.as_str().unwrap()); assert_eq!("hello\0world".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(t.as_cow_z_str().unwrap_err(), io::Errno::INVAL); - assert_eq!(t.clone().into_z_str().unwrap_err(), io::Errno::INVAL); + assert_eq!(t.as_cow_c_str().unwrap_err(), io::Errno::INVAL); + assert_eq!(t.clone().into_c_str().unwrap_err(), io::Errno::INVAL); } diff --git a/tests/process/weak.rs b/tests/process/weak.rs index fc66f4ad7..d4f00f999 100644 --- a/tests/process/weak.rs +++ b/tests/process/weak.rs @@ -30,7 +30,7 @@ use core::ffi::c_void; use core::ptr::null_mut; use core::sync::atomic::{self, AtomicPtr, Ordering}; use core::{marker, mem}; -use rustix::ffi::ZStr; +use rustix::ffi::CStr; const NULL: *mut c_void = null_mut(); const INVALID: *mut c_void = 1 as *mut c_void; @@ -107,7 +107,7 @@ impl Weak { } unsafe fn fetch(name: &str) -> *mut c_void { - let name = match ZStr::from_bytes_with_nul(name.as_bytes()) { + let name = match CStr::from_bytes_with_nul(name.as_bytes()) { Ok(c_str) => c_str, Err(..) => return null_mut(), };