Skip to content

Commit 6152b77

Browse files
committed
rust: error: Add Error::from_errno{_unchecked}()
Add a function to create `Error` values out of a kernel error return, which safely upholds the invariant that the error code is well-formed (negative and greater than -MAX_ERRNO). If a malformed code is passed in, it will be converted to EINVAL. Lina: Imported from rust-for-linux/rust as authored by Miguel and Fox with refactoring from Wedson, renamed from_kernel_errno() to from_errno(). Co-developed-by: Fox Chen <[email protected]> Signed-off-by: Fox Chen <[email protected]> Co-developed-by: Wedson Almeida Filho <[email protected]> Signed-off-by: Wedson Almeida Filho <[email protected]> Signed-off-by: Miguel Ojeda <[email protected]> Reviewed-by: Andreas Hindborg <[email protected]> Reviewed-by: Gary Guo <[email protected]> Reviewed-by: Martin Rodriguez Reboredo <[email protected]> Signed-off-by: Asahi Lina <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Mark the new associated functions as `#[allow(dead_code)]`. ] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 0d59baa commit 6152b77

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

rust/kernel/error.rs

+32
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,38 @@ pub mod code {
7272
pub struct Error(core::ffi::c_int);
7373

7474
impl Error {
75+
/// Creates an [`Error`] from a kernel error code.
76+
///
77+
/// It is a bug to pass an out-of-range `errno`. `EINVAL` would
78+
/// be returned in such a case.
79+
#[allow(dead_code)]
80+
pub(crate) fn from_errno(errno: core::ffi::c_int) -> Error {
81+
if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 {
82+
// TODO: Make it a `WARN_ONCE` once available.
83+
crate::pr_warn!(
84+
"attempted to create `Error` with out of range `errno`: {}",
85+
errno
86+
);
87+
return code::EINVAL;
88+
}
89+
90+
// INVARIANT: The check above ensures the type invariant
91+
// will hold.
92+
Error(errno)
93+
}
94+
95+
/// Creates an [`Error`] from a kernel error code.
96+
///
97+
/// # Safety
98+
///
99+
/// `errno` must be within error code range (i.e. `>= -MAX_ERRNO && < 0`).
100+
#[allow(dead_code)]
101+
unsafe fn from_errno_unchecked(errno: core::ffi::c_int) -> Error {
102+
// INVARIANT: The contract ensures the type invariant
103+
// will hold.
104+
Error(errno)
105+
}
106+
75107
/// Returns the kernel error code.
76108
pub fn to_errno(self) -> core::ffi::c_int {
77109
self.0

0 commit comments

Comments
 (0)