rust/kernel/str.rs

Source file repositories/reference/linux-study-clean/rust/kernel/str.rs

File Facts

System
Linux kernel
Corpus path
rust/kernel/str.rs
Extension
.rs
Size
31198 bytes
Lines
919
Domain
Rust Kernel Layer
Bucket
Rust API Membrane
Inferred role
Rust Kernel Layer: implementation source
Status
source implementation candidate

Why This File Exists

Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.

Dependency Surface

Detected Declarations

Annotated Snippet

if (0x20..0x7f).contains(&c) {
                // Printable character.
                f.write_char(c as char)?;
            } else {
                write!(f, "\\x{c:02x}")?;
            }
        }
        Ok(())
    }
}

/// Converts a mutable C string to a mutable byte slice.
///
/// # Safety
///
/// The caller must ensure that the slice ends in a NUL byte and contains no other NUL bytes before
/// the borrow ends and the underlying [`CStr`] is used.
unsafe fn to_bytes_mut(s: &mut CStr) -> &mut [u8] {
    // SAFETY: the cast from `&CStr` to `&[u8]` is safe since `CStr` has the same layout as `&[u8]`
    // (this is technically not guaranteed, but we rely on it here). The pointer dereference is
    // safe since it comes from a mutable reference which is guaranteed to be valid for writes.
    unsafe { &mut *(core::ptr::from_mut(s) as *mut [u8]) }
}

impl CStrExt for CStr {
    #[inline]
    #[expect(clippy::disallowed_methods, reason = "internal implementation")]
    unsafe fn from_char_ptr<'a>(ptr: *const c_char) -> &'a Self {
        // SAFETY: The safety preconditions are the same as for `CStr::from_ptr`.
        unsafe { CStr::from_ptr(ptr.cast()) }
    }

    #[inline]
    unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut Self {
        // SAFETY: the cast from `&[u8]` to `&CStr` is safe since the properties of `bytes` are
        // guaranteed by the safety precondition and `CStr` has the same layout as `&[u8]` (this is
        // technically not guaranteed, but we rely on it here). The pointer dereference is safe
        // since it comes from a mutable reference which is guaranteed to be valid for writes.
        unsafe { &mut *(core::ptr::from_mut(bytes) as *mut CStr) }
    }

    #[inline]
    #[expect(clippy::disallowed_methods, reason = "internal implementation")]
    fn as_char_ptr(&self) -> *const c_char {
        self.as_ptr().cast()
    }

    fn to_cstring(&self) -> Result<CString, AllocError> {
        CString::try_from(self)
    }

    fn make_ascii_lowercase(&mut self) {
        // SAFETY: This doesn't introduce or remove NUL bytes in the C string.
        unsafe { to_bytes_mut(self) }.make_ascii_lowercase();
    }

    fn make_ascii_uppercase(&mut self) {
        // SAFETY: This doesn't introduce or remove NUL bytes in the C string.
        unsafe { to_bytes_mut(self) }.make_ascii_uppercase();
    }

    fn to_ascii_lowercase(&self) -> Result<CString, AllocError> {
        let mut s = self.to_cstring()?;

        s.make_ascii_lowercase();

        Ok(s)
    }

    fn to_ascii_uppercase(&self) -> Result<CString, AllocError> {
        let mut s = self.to_cstring()?;

        s.make_ascii_uppercase();

        Ok(s)
    }
}

impl AsRef<BStr> for CStr {
    #[inline]
    fn as_ref(&self) -> &BStr {
        BStr::from_bytes(self.to_bytes())
    }
}

/// Creates a new [`CStr`] at compile time.
///
/// Rust supports C string literals since Rust 1.77, and they should be used instead of this macro
/// where possible. This macro exists to allow static *non-literal* C strings to be created at
/// compile time. This is most often used in other macros.

Annotation

Implementation Notes