1247b365dSWedson Almeida Filho // SPDX-License-Identifier: GPL-2.0 2247b365dSWedson Almeida Filho 3247b365dSWedson Almeida Filho //! Kernel errors. 4247b365dSWedson Almeida Filho //! 5247b365dSWedson Almeida Filho //! C header: [`include/uapi/asm-generic/errno-base.h`](../../../include/uapi/asm-generic/errno-base.h) 6247b365dSWedson Almeida Filho 776e2c2d9SWedson Almeida Filho use alloc::{ 876e2c2d9SWedson Almeida Filho alloc::{AllocError, LayoutError}, 976e2c2d9SWedson Almeida Filho collections::TryReserveError, 1076e2c2d9SWedson Almeida Filho }; 1176e2c2d9SWedson Almeida Filho 1276e2c2d9SWedson Almeida Filho use core::convert::From; 1376e2c2d9SWedson Almeida Filho use core::num::TryFromIntError; 1476e2c2d9SWedson Almeida Filho use core::str::Utf8Error; 15247b365dSWedson Almeida Filho 16247b365dSWedson Almeida Filho /// Contains the C-compatible error codes. 17247b365dSWedson Almeida Filho pub mod code { 184b0c68bdSFinn Behrens macro_rules! declare_err { 194b0c68bdSFinn Behrens ($err:tt $(,)? $($doc:expr),+) => { 204b0c68bdSFinn Behrens $( 214b0c68bdSFinn Behrens #[doc = $doc] 224b0c68bdSFinn Behrens )* 234b0c68bdSFinn Behrens pub const $err: super::Error = super::Error(-(crate::bindings::$err as i32)); 244b0c68bdSFinn Behrens }; 254b0c68bdSFinn Behrens } 264b0c68bdSFinn Behrens 27266def2aSViktor Garske declare_err!(EPERM, "Operation not permitted."); 28266def2aSViktor Garske declare_err!(ENOENT, "No such file or directory."); 29266def2aSViktor Garske declare_err!(ESRCH, "No such process."); 30266def2aSViktor Garske declare_err!(EINTR, "Interrupted system call."); 31266def2aSViktor Garske declare_err!(EIO, "I/O error."); 32266def2aSViktor Garske declare_err!(ENXIO, "No such device or address."); 33266def2aSViktor Garske declare_err!(E2BIG, "Argument list too long."); 34266def2aSViktor Garske declare_err!(ENOEXEC, "Exec format error."); 35266def2aSViktor Garske declare_err!(EBADF, "Bad file number."); 36266def2aSViktor Garske declare_err!(ECHILD, "Exec format error."); 37266def2aSViktor Garske declare_err!(EAGAIN, "Try again."); 384b0c68bdSFinn Behrens declare_err!(ENOMEM, "Out of memory."); 39266def2aSViktor Garske declare_err!(EACCES, "Permission denied."); 40266def2aSViktor Garske declare_err!(EFAULT, "Bad address."); 41266def2aSViktor Garske declare_err!(ENOTBLK, "Block device required."); 42266def2aSViktor Garske declare_err!(EBUSY, "Device or resource busy."); 43266def2aSViktor Garske declare_err!(EEXIST, "File exists."); 44266def2aSViktor Garske declare_err!(EXDEV, "Cross-device link."); 45266def2aSViktor Garske declare_err!(ENODEV, "No such device."); 46266def2aSViktor Garske declare_err!(ENOTDIR, "Not a directory."); 47266def2aSViktor Garske declare_err!(EISDIR, "Is a directory."); 48266def2aSViktor Garske declare_err!(EINVAL, "Invalid argument."); 49266def2aSViktor Garske declare_err!(ENFILE, "File table overflow."); 50266def2aSViktor Garske declare_err!(EMFILE, "Too many open files."); 51266def2aSViktor Garske declare_err!(ENOTTY, "Not a typewriter."); 52266def2aSViktor Garske declare_err!(ETXTBSY, "Text file busy."); 53266def2aSViktor Garske declare_err!(EFBIG, "File too large."); 54266def2aSViktor Garske declare_err!(ENOSPC, "No space left on device."); 55266def2aSViktor Garske declare_err!(ESPIPE, "Illegal seek."); 56266def2aSViktor Garske declare_err!(EROFS, "Read-only file system."); 57266def2aSViktor Garske declare_err!(EMLINK, "Too many links."); 58266def2aSViktor Garske declare_err!(EPIPE, "Broken pipe."); 59266def2aSViktor Garske declare_err!(EDOM, "Math argument out of domain of func."); 60266def2aSViktor Garske declare_err!(ERANGE, "Math result not representable."); 61247b365dSWedson Almeida Filho } 62247b365dSWedson Almeida Filho 63247b365dSWedson Almeida Filho /// Generic integer kernel error. 64247b365dSWedson Almeida Filho /// 65247b365dSWedson Almeida Filho /// The kernel defines a set of integer generic error codes based on C and 66247b365dSWedson Almeida Filho /// POSIX ones. These codes may have a more specific meaning in some contexts. 67247b365dSWedson Almeida Filho /// 68247b365dSWedson Almeida Filho /// # Invariants 69247b365dSWedson Almeida Filho /// 70247b365dSWedson Almeida Filho /// The value is a valid `errno` (i.e. `>= -MAX_ERRNO && < 0`). 71247b365dSWedson Almeida Filho #[derive(Clone, Copy, PartialEq, Eq)] 72247b365dSWedson Almeida Filho pub struct Error(core::ffi::c_int); 73247b365dSWedson Almeida Filho 74247b365dSWedson Almeida Filho impl Error { 75247b365dSWedson Almeida Filho /// Returns the kernel error code. 76*46384d09SAsahi Lina pub fn to_errno(self) -> core::ffi::c_int { 77247b365dSWedson Almeida Filho self.0 78247b365dSWedson Almeida Filho } 79247b365dSWedson Almeida Filho } 80247b365dSWedson Almeida Filho 8176e2c2d9SWedson Almeida Filho impl From<AllocError> for Error { 8276e2c2d9SWedson Almeida Filho fn from(_: AllocError) -> Error { 8376e2c2d9SWedson Almeida Filho code::ENOMEM 8476e2c2d9SWedson Almeida Filho } 8576e2c2d9SWedson Almeida Filho } 8676e2c2d9SWedson Almeida Filho 8776e2c2d9SWedson Almeida Filho impl From<TryFromIntError> for Error { 8876e2c2d9SWedson Almeida Filho fn from(_: TryFromIntError) -> Error { 8976e2c2d9SWedson Almeida Filho code::EINVAL 9076e2c2d9SWedson Almeida Filho } 9176e2c2d9SWedson Almeida Filho } 9276e2c2d9SWedson Almeida Filho 9376e2c2d9SWedson Almeida Filho impl From<Utf8Error> for Error { 9476e2c2d9SWedson Almeida Filho fn from(_: Utf8Error) -> Error { 9576e2c2d9SWedson Almeida Filho code::EINVAL 9676e2c2d9SWedson Almeida Filho } 9776e2c2d9SWedson Almeida Filho } 9876e2c2d9SWedson Almeida Filho 99247b365dSWedson Almeida Filho impl From<TryReserveError> for Error { 100247b365dSWedson Almeida Filho fn from(_: TryReserveError) -> Error { 101247b365dSWedson Almeida Filho code::ENOMEM 102247b365dSWedson Almeida Filho } 103247b365dSWedson Almeida Filho } 104247b365dSWedson Almeida Filho 10576e2c2d9SWedson Almeida Filho impl From<LayoutError> for Error { 10676e2c2d9SWedson Almeida Filho fn from(_: LayoutError) -> Error { 10776e2c2d9SWedson Almeida Filho code::ENOMEM 10876e2c2d9SWedson Almeida Filho } 10976e2c2d9SWedson Almeida Filho } 11076e2c2d9SWedson Almeida Filho 11176e2c2d9SWedson Almeida Filho impl From<core::fmt::Error> for Error { 11276e2c2d9SWedson Almeida Filho fn from(_: core::fmt::Error) -> Error { 11376e2c2d9SWedson Almeida Filho code::EINVAL 11476e2c2d9SWedson Almeida Filho } 11576e2c2d9SWedson Almeida Filho } 11676e2c2d9SWedson Almeida Filho 11776e2c2d9SWedson Almeida Filho impl From<core::convert::Infallible> for Error { 11876e2c2d9SWedson Almeida Filho fn from(e: core::convert::Infallible) -> Error { 11976e2c2d9SWedson Almeida Filho match e {} 12076e2c2d9SWedson Almeida Filho } 12176e2c2d9SWedson Almeida Filho } 12276e2c2d9SWedson Almeida Filho 123247b365dSWedson Almeida Filho /// A [`Result`] with an [`Error`] error type. 124247b365dSWedson Almeida Filho /// 125247b365dSWedson Almeida Filho /// To be used as the return type for functions that may fail. 126247b365dSWedson Almeida Filho /// 127247b365dSWedson Almeida Filho /// # Error codes in C and Rust 128247b365dSWedson Almeida Filho /// 129247b365dSWedson Almeida Filho /// In C, it is common that functions indicate success or failure through 130247b365dSWedson Almeida Filho /// their return value; modifying or returning extra data through non-`const` 131247b365dSWedson Almeida Filho /// pointer parameters. In particular, in the kernel, functions that may fail 132247b365dSWedson Almeida Filho /// typically return an `int` that represents a generic error code. We model 133247b365dSWedson Almeida Filho /// those as [`Error`]. 134247b365dSWedson Almeida Filho /// 135247b365dSWedson Almeida Filho /// In Rust, it is idiomatic to model functions that may fail as returning 136247b365dSWedson Almeida Filho /// a [`Result`]. Since in the kernel many functions return an error code, 137247b365dSWedson Almeida Filho /// [`Result`] is a type alias for a [`core::result::Result`] that uses 138247b365dSWedson Almeida Filho /// [`Error`] as its error type. 139247b365dSWedson Almeida Filho /// 140247b365dSWedson Almeida Filho /// Note that even if a function does not return anything when it succeeds, 141247b365dSWedson Almeida Filho /// it should still be modeled as returning a `Result` rather than 142247b365dSWedson Almeida Filho /// just an [`Error`]. 143247b365dSWedson Almeida Filho pub type Result<T = ()> = core::result::Result<T, Error>; 144