summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/path/arg.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/path/arg.rs')
-rw-r--r--vendor/rustix/src/path/arg.rs140
1 files changed, 129 insertions, 11 deletions
diff --git a/vendor/rustix/src/path/arg.rs b/vendor/rustix/src/path/arg.rs
index 64091611c..3b0ad91ae 100644
--- a/vendor/rustix/src/path/arg.rs
+++ b/vendor/rustix/src/path/arg.rs
@@ -5,16 +5,13 @@
//! 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, CString};
+use crate::ffi::CStr;
use crate::io;
#[cfg(feature = "itoa")]
use crate::path::DecInt;
use crate::path::SMALL_PATH_BUFFER_SIZE;
-use alloc::borrow::Cow;
-#[cfg(feature = "itoa")]
+#[cfg(all(feature = "alloc", feature = "itoa"))]
use alloc::borrow::ToOwned;
-use alloc::string::String;
-use alloc::vec::Vec;
use core::mem::MaybeUninit;
use core::{ptr, slice, str};
#[cfg(feature = "std")]
@@ -29,6 +26,10 @@ use std::os::vxworks::ext::ffi::{OsStrExt, OsStringExt};
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.
///
@@ -65,15 +66,18 @@ 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>`.
+ /// 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;
@@ -91,11 +95,13 @@ impl Arg for &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(
@@ -103,6 +109,7 @@ impl Arg for &str {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -123,17 +130,20 @@ impl Arg for &str {
}
}
+#[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(
@@ -141,6 +151,7 @@ impl Arg for &String {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -159,17 +170,20 @@ impl Arg for &String {
}
}
+#[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(
@@ -177,6 +191,7 @@ impl Arg for String {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -204,11 +219,13 @@ impl Arg for &OsStr {
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(
@@ -216,6 +233,7 @@ impl Arg for &OsStr {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -243,11 +261,13 @@ impl Arg for &OsString {
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(
@@ -256,6 +276,7 @@ impl Arg for &OsString {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -281,11 +302,13 @@ impl Arg for OsString {
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(
@@ -293,6 +316,7 @@ impl Arg for OsString {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -320,11 +344,13 @@ impl Arg for &Path {
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(
@@ -332,6 +358,7 @@ impl Arg for &Path {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -362,11 +389,13 @@ impl Arg for &PathBuf {
.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(
@@ -375,6 +404,7 @@ impl Arg for &PathBuf {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -400,11 +430,13 @@ impl Arg for PathBuf {
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(
@@ -412,6 +444,7 @@ impl Arg for PathBuf {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -441,16 +474,19 @@ impl Arg for &CStr {
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
@@ -469,22 +505,26 @@ impl Arg for &CStr {
}
}
+#[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
@@ -503,22 +543,26 @@ impl Arg for &CString {
}
}
+#[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
@@ -537,17 +581,20 @@ impl Arg for CString {
}
}
+#[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(
@@ -555,6 +602,7 @@ impl<'a> Arg for Cow<'a, str> {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -580,17 +628,20 @@ impl<'a> Arg for Cow<'a, str> {
}
#[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(
@@ -598,6 +649,7 @@ impl<'a> Arg for Cow<'a, OsStr> {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -622,23 +674,27 @@ impl<'a> Arg for Cow<'a, OsStr> {
}
}
+#[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
@@ -664,11 +720,13 @@ impl<'a> Arg for Component<'a> {
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(
@@ -676,6 +734,7 @@ impl<'a> Arg for Component<'a> {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -703,11 +762,13 @@ impl<'a> Arg for Components<'a> {
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(
@@ -716,6 +777,7 @@ impl<'a> Arg for Components<'a> {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -744,11 +806,13 @@ impl<'a> Arg for Iter<'a> {
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(
@@ -757,6 +821,7 @@ impl<'a> Arg for Iter<'a> {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -784,11 +849,13 @@ impl Arg for &[u8] {
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(
@@ -796,6 +863,7 @@ impl Arg for &[u8] {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -816,17 +884,20 @@ impl Arg for &[u8] {
}
}
+#[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(
@@ -834,6 +905,7 @@ impl Arg for &Vec<u8> {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -854,17 +926,20 @@ impl Arg for &Vec<u8> {
}
}
+#[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(
@@ -872,6 +947,7 @@ impl Arg for Vec<u8> {
))
}
+ #[cfg(feature = "alloc")]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
where
@@ -899,16 +975,19 @@ impl Arg for DecInt {
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
@@ -961,19 +1040,58 @@ where
}
// 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.
+ // 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.
+/// 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>,
{
- f(&CString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?)
+ #[cfg(feature = "alloc")]
+ {
+ f(&CString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?)
+ }
+
+ #[cfg(not(feature = "alloc"))]
+ {
+ #[cfg(libc)]
+ 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;
+
+ // 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),
+ }
+ }
}