let const_ptr: *const crate::ffi::c_void = ptr.cast(); // SAFETY: The FFI function does not deref the pointer. if unsafe { bindings::IS_ERR(const_ptr) } { // SAFETY: The FFI function does not deref the pointer. let err = unsafe { bindings::PTR_ERR(const_ptr) }; #[allow(clippy::unnecessary_cast)] // CAST: If `IS_ERR()` returns `true`, // then `PTR_ERR()` is guaranteed to return a // negative value greater-or-equal to `-bindings::MAX_ERRNO`, // which always fits in an `i16`, as per the invariant above. // And an `i16` always fits in an `i32`. So casting `err` to // an `i32` can never overflow, and is always valid. // // SAFETY: `IS_ERR()` ensures `err` is a // negative value greater-or-equal to `-bindings::MAX_ERRNO`. return Err(unsafe { Error::from_errno_unchecked(err as crate::ffi::c_int) }); } Ok(ptr)} /// Calls a closure returning a [`crate::error::Result<T>`] and converts the result to/// a C integer result.////// This is useful when calling Rust functions that return [`crate::error::Result<T>`]/// from inside `extern "C"` functions that need to return an integer error result.////// `T` should be convertible from an `i16` via `From<i16>`.////// # Examples////// ```ignore/// # use kernel::from_result;/// # use kernel::bindings;/// unsafe extern "C" fn probe_callback(/// pdev: *mut bindings::platform_device,/// ) -> kernel::ffi::c_int {/// from_result(|| {/// let ptr = devm_alloc(pdev)?;/// bindings::platform_set_drvdata(pdev, ptr);/// Ok(0)/// })/// }/// ```pub fn from_result<T, F>(f: F) -> Twhere T: From<i16>, F: FnOnce() -> Result<T>,{ match f() { Ok(v) => v, // NO-OVERFLOW: negative `errno`s are no smaller than `-bindings::MAX_ERRNO`, // `-bindings::MAX_ERRNO` fits in an `i16` as per invariant above, // therefore a negative `errno` always fits in an `i16` and will not overflow. Err(e) => T::from(e.to_errno() as i16), }} /// Error message for calling a default function of a [`#[vtable]`](macros::vtable) trait.pub const VTABLE_DEFAULT_ERROR: &str = "This function must not be called, see the #[vtable] documentation.";Lines 501–561 of 561. Previous lines
let const_ptr: *const crate::ffi::c_void = ptr.cast(); // SAFETY: The FFI function does not deref the pointer. if unsafe { bindings::IS_ERR(const_ptr) } { // SAFETY: The FFI function does not deref the pointer. let err = unsafe { bindings::PTR_ERR(const_ptr) }; #[allow(clippy::unnecessary_cast)] // CAST: If `IS_ERR()` returns `true`, // then `PTR_ERR()` is guaranteed to return a // negative value greater-or-equal to `-bindings::MAX_ERRNO`, // which always fits in an `i16`, as per the invariant above. // And an `i16` always fits in an `i32`. So casting `err` to // an `i32` can never overflow, and is always valid. // // SAFETY: `IS_ERR()` ensures `err` is a // negative value greater-or-equal to `-bindings::MAX_ERRNO`. return Err(unsafe { Error::from_errno_unchecked(err as crate::ffi::c_int) }); } Ok(ptr) } /// Calls a closure returning a [`crate::error::Result<T>`] and converts the result to /// a C integer result. /// /// This is useful when calling Rust functions that return [`crate::error::Result<T>`] /// from inside `extern "C"` functions that need to return an integer error result. /// /// `T` should be convertible from an `i16` via `From<i16>`. /// /// # Examples /// /// ```ignore /// # use kernel::from_result; /// # use kernel::bindings; /// unsafe extern "C" fn probe_callback( /// pdev: *mut bindings::platform_device, /// ) -> kernel::ffi::c_int { /// from_result(|| { /// let ptr = devm_alloc(pdev)?; /// bindings::platform_set_drvdata(pdev, ptr); /// Ok(0) /// }) /// } /// ``` pub fn from_result<T, F>(f: F) -> T where T: From<i16>, F: FnOnce() -> Result<T>, { match f() { Ok(v) => v, // NO-OVERFLOW: negative `errno`s are no smaller than `-bindings::MAX_ERRNO`, // `-bindings::MAX_ERRNO` fits in an `i16` as per invariant above, // therefore a negative `errno` always fits in an `i16` and will not overflow. Err(e) => T::from(e.to_errno() as i16), } } /// Error message for calling a default function of a [`#[vtable]`](macros::vtable) trait. pub const VTABLE_DEFAULT_ERROR: &str = "This function must not be called, see the #[vtable] documentation.";