commit d4ae3a022556928177007bfb37e700369f15d6cf
parent 6caca4961a51443ea5ee79d32d5d1a80061663dc
Author: Zack Newman <zack@philomathiclife.com>
Date: Sat, 10 Jan 2026 17:06:00 -0700
improve docs. impl CStrHelper for mut refs
Diffstat:
4 files changed, 79 insertions(+), 18 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -10,7 +10,7 @@ name = "priv_sep"
readme = "README.md"
repository = "https://git.philomathiclife.com/repos/priv_sep/"
rust-version = "1.86.0"
-version = "3.0.0-alpha.3.0"
+version = "3.0.0-alpha.4.0"
[lints.rust]
ambiguous_negative_literals = { level = "deny", priority = -1 }
diff --git a/README.md b/README.md
@@ -102,6 +102,23 @@ async fn main() -> Result<Infallible, PrivDropErr<Error>> {
```
</details>
+## Cargo "features"
+
+### `alloc`
+
+Enables `alloc` support. While "typical" use of `priv_sep` should work without `alloc`, there are cases
+where one may desire heap allocation. For example if a database entry associated with a user requires
+more than 1 KiB of space, `UserInfo::new` will error with `Errno::ERANGE` when `alloc` is not enabled.
+
+Additional `CStrHelper` `impl`s are exposed as well (e.g., `String`).
+
+### `std`
+
+Enables `std` support. This is useful for additional `CStrHelper` `impl`s (e.g., `OsStr`) as well as
+`TryFrom<Error>` and `From<Errno>`.
+
+This feature implies [`alloc`](#alloc) and is enabled by default via the `default` feature.
+
## Minimum Supported Rust Version (MSRV)
This will frequently be updated to be the same as stable. Specifically, any time stable is updated and that
diff --git a/src/lib.rs b/src/lib.rs
@@ -107,6 +107,26 @@
//! }
//! ```
//! </details>
+//!
+//! ## Cargo "features"
+//!
+//! ### `alloc`
+//!
+//! Enables `alloc` support. While "typical" use of `priv_sep` should work without `alloc`, there are cases
+//! where one may desire heap allocation. For example if a database entry associated with a user requires
+//! more than 1 KiB of space, [`UserInfo::new`] will error with [`Errno::ERANGE`] when `alloc` is not enabled.
+//!
+//! Additional [`CStrHelper`] `impl`s are exposed as well (e.g.,
+//! [`String`](./trait.CStrHelper.html#impl-CStrHelper-for-String)).
+//!
+//! ### `std`
+//!
+//! Enables `std` support. This is useful for additional [`CStrHelper`] `impl`s (e.g.,
+//! [`OsStr`](./trait.CStrHelper.html#impl-CStrHelper-for-OsStr)) as well as
+//! [`TryFrom<Error>`](./enum.Errno.html#impl-TryFrom%3CError%3E-for-Errno)
+//! and [`From<Errno>`](./enum.Errno.html#impl-From%3CErrno%3E-for-Error).
+//!
+//! This feature implies [`alloc`](#alloc) and is enabled by default via the `default` feature.
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, doc(auto_cfg = false))]
#![no_std]
@@ -357,20 +377,22 @@ impl From<u32> for Gid {
Self(value)
}
}
-/// Primarily an internal `trait` that allows one to use other types in lieu of
+/// Primarily an internal `trait` that allows one to use a variety of types in lieu of
/// [`CStr`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html).
pub trait CStrHelper {
- /// First converts `self` into a `CStr` before passing it into `f`.
+ /// First converts `self` into a
+ /// [`CStr`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html)
+ /// before passing it into `f`.
///
/// # Errors
///
/// Errors whenever necessary.
///
- /// If an error occurs due to insufficient buffer space (e.g., when the `alloc` feature is not enabled and
- /// a `str` is used with length greater than 1023), then [`Errno::ERANGE`] must be returned.
+ /// If an error occurs due to insufficient buffer space (e.g., when [`alloc`](./index.html#alloc) is not
+ /// enabled and a `str` is used with length greater than 1023), then [`Errno::ERANGE`] must be returned.
///
- /// If an error occurs from converting `self` into a `CStr` due to nul bytes, then [`Errno::EINVAL`] must be
- /// returned.
+ /// If an error occurs from converting `self` into a `CStr` due to nul bytes, then [`Errno::EINVAL`]
+ /// must be returned.
fn convert_then_apply<T, F: FnOnce(&CStr) -> Result<T, Errno>>(&self, f: F)
-> Result<T, Errno>;
}
@@ -383,6 +405,17 @@ impl CStrHelper for CStr {
f(self)
}
}
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+#[cfg(feature = "alloc")]
+impl CStrHelper for CString {
+ #[inline]
+ fn convert_then_apply<T, F: FnOnce(&CStr) -> Result<T, Errno>>(
+ &self,
+ f: F,
+ ) -> Result<T, Errno> {
+ self.as_c_str().convert_then_apply(f)
+ }
+}
/// Converts `val` into a `CStr` via heap allocation before applying `f` to it.
#[cold]
#[inline(never)]
@@ -407,7 +440,7 @@ impl CStrHelper for [u8] {
f: F,
) -> Result<T, Errno> {
/// Maximum stack allocation for `CStr` conversion.
- const C_STR_MAX_STACK_ALLOCATION: usize = 1024;
+ const C_STR_MAX_STACK_ALLOCATION: usize = 0x400;
let len = self.len();
if len < C_STR_MAX_STACK_ALLOCATION {
let mut buf = MaybeUninit::<[u8; C_STR_MAX_STACK_ALLOCATION]>::uninit();
@@ -563,6 +596,15 @@ impl<C: CStrHelper + ?Sized> CStrHelper for &C {
(**self).convert_then_apply(f)
}
}
+impl<C: CStrHelper + ?Sized> CStrHelper for &mut C {
+ #[inline]
+ fn convert_then_apply<T, F: FnOnce(&CStr) -> Result<T, Errno>>(
+ &self,
+ f: F,
+ ) -> Result<T, Errno> {
+ (**self).convert_then_apply(f)
+ }
+}
/// [`chroot(2)`](https://manned.org/chroot.2).
///
/// # Errors
@@ -820,13 +862,13 @@ impl UserInfo {
///
/// Obtains the user database entry returning `None` iff there is no entry; otherwise returns `Self`.
///
- /// A 1024-byte stack-allocated buffer is used to write the database entry into. If [`Errno::ERANGE`]
+ /// A 1 KiB stack-allocated buffer is used to write the database entry into. If [`Errno::ERANGE`]
/// is returned, then the following will occur:
///
- /// * If `alloc` is not enabled, then the error is returned.
- /// * If `alloc` is enabled and a 16-bit architecture is used, then a heap-allocated buffer of 16 KiB
+ /// * If [`alloc`](./index.html#alloc) is not enabled, then the error is returned.
+ /// * If [`alloc`](./index.html#alloc) is enabled and a 16-bit architecture is used, then a heap-allocated buffer of 16 KiB
/// is used. If this errors, then the error is returned.
- /// * If `alloc` is enabled and a non-16-bit architecture is used, then a heap-allocated buffer of 1 MiB
+ /// * If [`alloc`](./index.html#alloc) is enabled and a non-16-bit architecture is used, then a heap-allocated buffer of 1 MiB
/// is used. If this errors, then the error is returned.
///
/// # Errors
@@ -893,7 +935,7 @@ impl UserInfo {
/// Note this should rarely be used since most will rely on [`Self::new`], [`Self::priv_drop`], or
/// [`Self::chroot_then_priv_drop`].
///
- /// Read [`Self::new`] more information on the buffering strategy.
+ /// Read [`Self::new`] for more information on the buffering strategy.
///
/// # Errors
///
@@ -1195,7 +1237,7 @@ pub fn setgroups(groups: &[Gid]) -> Result<(), Errno> {
let size = c_int::try_from(groups.len()).map_err(|_e| Errno::EINVAL)?;
let gids = groups.as_ptr().cast();
// SAFETY:
- // `size` is the length of `gids`, and `gids` is a valid, non-null, alligned pointer to
+ // `size` is the length of `gids`, and `gids` is a valid, non-null, aligned pointer to
// `u32`s. Note that `Gid` is a `newtype` around `u32` with `repr(transparent)`; thus the above
// pointer cast is fine.
let code = unsafe { c::setgroups(size, gids) };
diff --git a/src/openbsd.rs b/src/openbsd.rs
@@ -1113,8 +1113,9 @@ impl Promises {
// `NULL` is always valid for `promises`.
Self::inner_pledge(ptr::null())
}
- /// Invokes [`pledge(2)`](https://man.openbsd.org/pledge.2) with [`CStr::as_ptr`] from `promises` for
- /// `promises` and `NULL` for `execpromises`.
+ /// Invokes [`pledge(2)`](https://man.openbsd.org/pledge.2) with
+ /// [`CStr::as_ptr`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html#method.as_ptr)
+ /// from `promises` for `promises` and `NULL` for `execpromises`.
///
/// Exposes an API that allows one to `pledge(2)` "directly".
///
@@ -1334,8 +1335,9 @@ impl Permissions {
// `NULL` is valid for both `path` and `permissions`.
Self::inner_unveil(ptr::null(), ptr::null())
}
- /// Invokes [`unveil(2)`](https://man.openbsd.org/unveil.2)
- /// passing [`CStr::as_ptr`] from `path` for `path` and `permissions.as_ptr()` for `permissions`.
+ /// Invokes [`unveil(2)`](https://man.openbsd.org/unveil.2) passing
+ /// [`CStr::as_ptr`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html#method.as_ptr)
+ /// from `path` for `path` and `permissions.as_ptr()` for `permissions`.
///
/// Exposes an API that allows one to `unveil(2)` "directly".
///