diff options
Diffstat (limited to 'vendor/rustix/src/path')
-rw-r--r-- | vendor/rustix/src/path/arg.rs | 1099 | ||||
-rw-r--r-- | vendor/rustix/src/path/dec_int.rs | 120 | ||||
-rw-r--r-- | vendor/rustix/src/path/mod.rs | 12 |
3 files changed, 0 insertions, 1231 deletions
diff --git a/vendor/rustix/src/path/arg.rs b/vendor/rustix/src/path/arg.rs deleted file mode 100644 index f71125d..0000000 --- a/vendor/rustix/src/path/arg.rs +++ /dev/null @@ -1,1099 +0,0 @@ -//! Convenient and efficient string argument passing. -//! -//! This module defines the `Arg` trait and implements it for several common -//! string types. This allows users to pass any of these string types directly -//! to rustix APIs with string arguments, and it allows rustix to implement -//! NUL-termination without the need for copying where possible. - -use crate::ffi::CStr; -use crate::io; -#[cfg(feature = "itoa")] -use crate::path::DecInt; -use crate::path::SMALL_PATH_BUFFER_SIZE; -#[cfg(all(feature = "alloc", feature = "itoa"))] -use alloc::borrow::ToOwned; -use core::mem::MaybeUninit; -use core::{ptr, slice, str}; -#[cfg(feature = "std")] -use std::ffi::{OsStr, OsString}; -#[cfg(all(feature = "std", target_os = "hermit"))] -use std::os::hermit::ext::ffi::{OsStrExt, OsStringExt}; -#[cfg(all(feature = "std", unix))] -use std::os::unix::ffi::{OsStrExt, OsStringExt}; -#[cfg(all(feature = "std", target_os = "vxworks"))] -use std::os::vxworks::ext::ffi::{OsStrExt, OsStringExt}; -#[cfg(all(feature = "std", target_os = "wasi"))] -use std::os::wasi::ffi::{OsStrExt, OsStringExt}; -#[cfg(feature = "std")] -use std::path::{Component, Components, Iter, Path, PathBuf}; -#[cfg(feature = "alloc")] -use {crate::ffi::CString, alloc::borrow::Cow}; -#[cfg(feature = "alloc")] -use {alloc::string::String, alloc::vec::Vec}; - -/// A trait for passing path arguments. -/// -/// This is similar to [`AsRef`]`<`[`Path`]`>`, but is implemented for more -/// kinds of strings and can convert into more kinds of strings. -/// -/// # Examples -/// -/// ``` -/// # #[cfg(any(feature = "fs", feature = "net"))] -/// 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<P: Arg>(path: P) -> io::Result<()> { -/// let path = path.into_c_str()?; -/// _touch(&path) -/// } -/// -/// # #[cfg(any(feature = "fs", feature = "net"))] -/// fn _touch(path: &CStr) -> io::Result<()> { -/// // implementation goes here -/// Ok(()) -/// } -/// ``` -/// -/// Users can then call `touch("foo")`, `touch(cstr!("foo"))`, -/// `touch(Path::new("foo"))`, or many other things. -/// -/// [`AsRef`]: std::convert::AsRef -pub trait Arg { - /// Returns a view of this string as a string slice. - fn as_str(&self) -> io::Result<&str>; - - /// Returns a potentially-lossy rendering of this string as a - /// `Cow<'_, str>`. - #[cfg(feature = "alloc")] - fn to_string_lossy(&self) -> Cow<'_, str>; - - /// Returns a view of this string as a maybe-owned [`CStr`]. - #[cfg(feature = "alloc")] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>>; - - /// Consumes `self` and returns a view of this string as a maybe-owned - /// [`CStr`]. - #[cfg(feature = "alloc")] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b; - - /// Runs a closure with `self` passed in as a `&CStr`. - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>; -} - -impl Arg for &str { - #[inline] - fn as_str(&self) -> io::Result<&str> { - Ok(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(*self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "alloc")] -impl Arg for &String { - #[inline] - fn as_str(&self) -> io::Result<&str> { - Ok(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(String::as_str(self)).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - self.as_str().into_c_str() - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "alloc")] -impl Arg for String { - #[inline] - fn as_str(&self) -> io::Result<&str> { - Ok(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_str()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(&CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?) - } -} - -#[cfg(feature = "std")] -impl Arg for &OsStr { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.to_str().ok_or(io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - OsStr::to_string_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "std")] -impl Arg for &OsString { - #[inline] - fn as_str(&self) -> io::Result<&str> { - OsString::as_os_str(self).to_str().ok_or(io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_os_str().to_string_lossy() - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(OsString::as_os_str(self).as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - self.as_os_str().into_c_str() - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "std")] -impl Arg for OsString { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_os_str().to_str().ok_or(io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_os_str().to_string_lossy() - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(&CString::new(self.into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?) - } -} - -#[cfg(feature = "std")] -impl Arg for &Path { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_os_str().to_str().ok_or(io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Path::to_string_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_os_str().as_bytes(), f) - } -} - -#[cfg(feature = "std")] -impl Arg for &PathBuf { - #[inline] - fn as_str(&self) -> io::Result<&str> { - PathBuf::as_path(self) - .as_os_str() - .to_str() - .ok_or(io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_path().to_string_lossy() - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(PathBuf::as_path(self).as_os_str().as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - self.as_path().into_c_str() - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_os_str().as_bytes(), f) - } -} - -#[cfg(feature = "std")] -impl Arg for PathBuf { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_os_str().to_str().ok_or(io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_os_str().to_string_lossy() - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.into_os_string().into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f( - &CString::new(self.into_os_string().into_vec()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - ) - } -} - -impl Arg for &CStr { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.to_str().map_err(|_utf8_err| io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - CStr::to_string_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Borrowed(self)) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Borrowed(self)) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(self) - } -} - -#[cfg(feature = "alloc")] -impl Arg for &CString { - #[inline] - fn as_str(&self) -> io::Result<&str> { - unimplemented!() - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - unimplemented!() - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Borrowed(self)) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Borrowed(self)) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(self) - } -} - -#[cfg(feature = "alloc")] -impl Arg for CString { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.to_str().map_err(|_utf8_err| io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - CStr::to_string_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Borrowed(self)) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned(self)) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(&self) - } -} - -#[cfg(feature = "alloc")] -impl<'a> Arg for Cow<'a, str> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - Ok(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_ref()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - match self { - Cow::Owned(s) => CString::new(s), - Cow::Borrowed(s) => CString::new(s), - } - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "std")] -#[cfg(feature = "alloc")] -impl<'a> Arg for Cow<'a, OsStr> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - (**self).to_str().ok_or(io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - (**self).to_string_lossy() - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - match self { - 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_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "alloc")] -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) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - let borrow: &CStr = core::borrow::Borrow::borrow(self); - borrow.to_string_lossy() - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Borrowed(self)) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(self) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(&self) - } -} - -#[cfg(feature = "std")] -impl<'a> Arg for Component<'a> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_os_str().to_str().ok_or(io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_os_str().to_string_lossy() - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_os_str().as_bytes(), f) - } -} - -#[cfg(feature = "std")] -impl<'a> Arg for Components<'a> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_path().to_str().ok_or(io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_path().to_string_lossy() - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_path().as_os_str().as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_path().as_os_str().as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_path().as_os_str().as_bytes(), f) - } -} - -#[cfg(feature = "std")] -impl<'a> Arg for Iter<'a> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_path().to_str().ok_or(io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_path().to_string_lossy() - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_path().as_os_str().as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_path().as_os_str().as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_path().as_os_str().as_bytes(), f) - } -} - -impl Arg for &[u8] { - #[inline] - fn as_str(&self) -> io::Result<&str> { - str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - String::from_utf8_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(*self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self, f) - } -} - -#[cfg(feature = "alloc")] -impl Arg for &Vec<u8> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - String::from_utf8_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self, f) - } -} - -#[cfg(feature = "alloc")] -impl Arg for Vec<u8> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - String::from_utf8_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(&CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?) - } -} - -#[cfg(feature = "itoa")] -impl Arg for DecInt { - #[inline] - fn as_str(&self) -> io::Result<&str> { - Ok(self.as_str()) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self.as_str()) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Borrowed(self.as_c_str())) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned(self.as_c_str().to_owned())) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(self.as_c_str()) - } -} - -/// Runs a closure with `bytes` passed in as a `&CStr`. -#[allow(unsafe_code, clippy::int_plus_one)] -#[inline] -fn with_c_str<T, F>(bytes: &[u8], f: F) -> io::Result<T> -where - F: FnOnce(&CStr) -> io::Result<T>, -{ - // 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 - // directory with a long path, consider opening the directory and using - // `openat` to open the files under it, which will avoid this, and is often - // faster in the OS as well. - - // Test with >= so that we have room for the trailing NUL. - if bytes.len() >= SMALL_PATH_BUFFER_SIZE { - return with_c_str_slow_path(bytes, f); - } - - // Taken from - // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs> - let mut buf = MaybeUninit::<[u8; SMALL_PATH_BUFFER_SIZE]>::uninit(); - let buf_ptr = buf.as_mut_ptr().cast::<u8>(); - - // This helps test our safety condition below. - debug_assert!(bytes.len() + 1 <= SMALL_PATH_BUFFER_SIZE); - - // SAFETY: `bytes.len() < SMALL_PATH_BUFFER_SIZE` which means we have space - // for `bytes.len() + 1` u8s: - unsafe { - ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len()); - buf_ptr.add(bytes.len()).write(0); - } - - // SAFETY: We just wrote the bytes above and they will remain valid for the - // duration of `f` b/c buf doesn't get dropped until the end of the - // function. - match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) { - Ok(s) => f(s), - Err(_) => 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. -#[allow(unsafe_code, clippy::int_plus_one)] -#[cold] -fn with_c_str_slow_path<T, F>(bytes: &[u8], f: F) -> io::Result<T> -where - F: FnOnce(&CStr) -> io::Result<T>, -{ - #[cfg(feature = "alloc")] - { - f(&CString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?) - } - - #[cfg(not(feature = "alloc"))] - { - #[cfg(all(libc, not(target_os = "wasi")))] - const LARGE_PATH_BUFFER_SIZE: usize = libc::PATH_MAX as usize; - #[cfg(linux_raw)] - const LARGE_PATH_BUFFER_SIZE: usize = linux_raw_sys::general::PATH_MAX as usize; - #[cfg(target_os = "wasi")] - const LARGE_PATH_BUFFER_SIZE: usize = 4096 as usize; // TODO: upstream this - - // Taken from - // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs> - let mut buf = MaybeUninit::<[u8; LARGE_PATH_BUFFER_SIZE]>::uninit(); - let buf_ptr = buf.as_mut_ptr().cast::<u8>(); - - // This helps test our safety condition below. - if bytes.len() + 1 > LARGE_PATH_BUFFER_SIZE { - return Err(io::Errno::NAMETOOLONG); - } - - // SAFETY: `bytes.len() < LARGE_PATH_BUFFER_SIZE` which means we have - // space for `bytes.len() + 1` u8s: - unsafe { - ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len()); - buf_ptr.add(bytes.len()).write(0); - } - - // SAFETY: We just wrote the bytes above and they will remain valid for - // the duration of `f` b/c buf doesn't get dropped until the end of the - // function. - match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) - { - Ok(s) => f(s), - Err(_) => Err(io::Errno::INVAL), - } - } -} diff --git a/vendor/rustix/src/path/dec_int.rs b/vendor/rustix/src/path/dec_int.rs deleted file mode 100644 index e9c46f4..0000000 --- a/vendor/rustix/src/path/dec_int.rs +++ /dev/null @@ -1,120 +0,0 @@ -//! Efficient decimal integer formatting. -//! -//! # Safety -//! -//! This uses `CStr::from_bytes_with_nul_unchecked` and -//! `str::from_utf8_unchecked`on the buffer that it filled itself. -#![allow(unsafe_code)] - -use crate::backend::fd::{AsFd, AsRawFd}; -use crate::ffi::CStr; -use core::fmt::Write; -use itoa::{Buffer, Integer}; -#[cfg(all(feature = "std", unix))] -use std::os::unix::ffi::OsStrExt; -#[cfg(all(feature = "std", target_os = "wasi"))] -use std::os::wasi::ffi::OsStrExt; -#[cfg(feature = "std")] -use {core::fmt, std::ffi::OsStr, std::path::Path}; - -/// Format an integer into a decimal `Path` component, without constructing a -/// temporary `PathBuf` or `String`. -/// -/// This is used for opening paths such as `/proc/self/fd/<fd>` on Linux. -/// -/// # Examples -/// -/// ``` -/// # #[cfg(any(feature = "fs", feature = "net"))] -/// use rustix::path::DecInt; -/// -/// # #[cfg(any(feature = "fs", feature = "net"))] -/// assert_eq!( -/// format!("hello {}", DecInt::new(9876).as_ref().display()), -/// "hello 9876" -/// ); -/// ``` -#[derive(Clone)] -pub struct DecInt { - // 20 `u8`s is enough to hold the decimal ASCII representation of any - // `u64`, and we add one for a NUL terminator for `as_c_str`. - buf: [u8; 20 + 1], - len: usize, -} - -impl DecInt { - /// Construct a new path component from an integer. - #[inline] - pub fn new<Int: Integer>(i: Int) -> Self { - let mut me = DecIntWriter(Self { - buf: [0; 20 + 1], - len: 0, - }); - let mut buf = Buffer::new(); - me.write_str(buf.format(i)).unwrap(); - me.0 - } - - /// Construct a new path component from a file descriptor. - #[inline] - pub fn from_fd<Fd: AsFd>(fd: Fd) -> Self { - Self::new(fd.as_fd().as_raw_fd()) - } - - /// Return the raw byte buffer as a `&str`. - #[inline] - pub fn as_str(&self) -> &str { - // SAFETY: `DecInt` always holds a formatted decimal number, so it's - // always valid UTF-8. - unsafe { core::str::from_utf8_unchecked(self.as_bytes()) } - } - - /// Return the raw byte buffer as a `&CStr`. - #[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) } - } - - /// Return the raw byte buffer. - #[inline] - pub fn as_bytes(&self) -> &[u8] { - &self.buf[..self.len] - } -} - -struct DecIntWriter(DecInt); - -impl core::fmt::Write for DecIntWriter { - #[inline] - fn write_str(&mut self, s: &str) -> core::fmt::Result { - match self.0.buf.get_mut(self.0.len..self.0.len + s.len()) { - Some(slice) => { - slice.copy_from_slice(s.as_bytes()); - self.0.len += s.len(); - Ok(()) - } - None => Err(core::fmt::Error), - } - } -} - -#[cfg(feature = "std")] -impl AsRef<Path> for DecInt { - #[inline] - fn as_ref(&self) -> &Path { - let as_os_str: &OsStr = OsStrExt::from_bytes(&self.buf[..self.len]); - Path::new(as_os_str) - } -} - -#[cfg(feature = "std")] -impl fmt::Debug for DecInt { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - self.as_str().fmt(fmt) - } -} diff --git a/vendor/rustix/src/path/mod.rs b/vendor/rustix/src/path/mod.rs deleted file mode 100644 index 19bf2c7..0000000 --- a/vendor/rustix/src/path/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! Filesystem path operations. - -mod arg; -#[cfg(feature = "itoa")] -mod dec_int; - -pub use arg::Arg; -#[cfg(feature = "itoa")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "itoa")))] -pub use dec_int::DecInt; - -pub(crate) const SMALL_PATH_BUFFER_SIZE: usize = 256; |