rust-kernel
Rustbelt: a hobby x86_64 kernel written in Rust
4355 bytes ยท raw
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | //! Error numbers, same values as Linux (`man 3 errno`). Syscalls return
//! `-errno` in rax on failure, like Linux does.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(i64)]
pub enum Errno {
EPERM = 1, // operation not permitted (e.g. setpgid on a stranger)
ENOENT = 2, // no such file or directory
ESRCH = 3, // no such process (kill)
EINTR = 4, // interrupted by a signal
EIO = 5, // input/output error (disk trouble; a pty whose other end closed)
ENXIO = 6, // no such device (/dev/tty without a controlling terminal)
E2BIG = 7, // argument list too long
ENOEXEC = 8, // not a valid executable
EBADF = 9, // bad file descriptor
ECHILD = 10, // no such child process (wait)
EAGAIN = 11, // try again (wait with WNOHANG: child still running)
ENOMEM = 12, // out of memory
EFAULT = 14, // bad address (pointer not in user space / not mapped)
EBUSY = 16, // busy (e.g. removing a mount point)
EEXIST = 17, // file exists
EXDEV = 18, // can't do this across file systems (rename: copy instead)
ENODEV = 19, // no such device (e.g. no GPU for a framebuffer ioctl)
ENOTDIR = 20, // a path component isn't a directory
EISDIR = 21, // is a directory
EINVAL = 22, // invalid argument
EMFILE = 24, // too many open files
ENOSPC = 28, // no space left on device
ENOTTY = 25, // not a terminal (ioctl on a file)
EFBIG = 27, // file too large
ESPIPE = 29, // can't seek (pipe, console)
EROFS = 30, // read-only file system
EPIPE = 32, // writing to a pipe nobody reads
ERANGE = 34, // result doesn't fit (getcwd buffer too small)
EDEADLK = 35, // waiting for this lock would deadlock (fcntl F_SETLKW)
ENAMETOOLONG = 36, // path too long
ENOLCK = 37, // no locks available (the record-lock table is full)
ENOSYS = 38, // no such system call
ENOTEMPTY = 39, // directory not empty
ELOOP = 40, // too many symlinks in a row (a loop?)
EOPNOTSUPP = 95, // operation not supported (by this file system)
// Networking.
ENOTSOCK = 88, // socket call on something that isn't a socket
EDESTADDRREQ = 89, // send on an unconnected socket without an address
EMSGSIZE = 90, // datagram too big
ENOPROTOOPT = 92, // unknown socket option (setsockopt)
EPROTONOSUPPORT = 93, // unsupported protocol (socket())
EAFNOSUPPORT = 97, // unsupported address family (only AF_INET)
EADDRINUSE = 98, // port already in use
ENETDOWN = 100, // no network card
ENETUNREACH = 101, // no IP address (yet): DHCP didn't answer
ECONNRESET = 104, // connection reset by the other side
EISCONN = 106, // already connected
ENOTCONN = 107, // not connected
ETIMEDOUT = 110, // connect/DNS timed out
ECONNREFUSED = 111, // nobody listens on that port (got a RST)
EINPROGRESS = 115, // nonblocking connect: started, not done yet
// Kernel-internal (never seen by programs): "a signal interrupted this
// call". On the way back to user space signal.rs turns them into
// EINTR or restarts the call (Linux uses the same numbers).
ERESTARTSYS = 512, // restart if no handler ran, or it has SA_RESTART
ERESTARTNOHAND = 514, // restart only if no handler ran (pause, sleep)
}
impl Errno {
/// The errno for a negative syscall result like -2, if we know it.
pub fn from_ret(ret: i64) -> Option<Errno> {
use Errno::*;
const ALL: [Errno; 52] = [
EPERM, ESRCH, EINTR, ERESTARTSYS, ERESTARTNOHAND, ENOENT, EIO, E2BIG, ENOEXEC, EBADF, ECHILD, EAGAIN, ENOMEM, EFAULT, EBUSY, EEXIST, ENODEV,
ENOTDIR, EISDIR, EINVAL, EMFILE, ENOTTY, EFBIG, ENOSPC, ESPIPE, EROFS, EPIPE, ERANGE,
ENAMETOOLONG, ENOSYS, ENOTEMPTY, ELOOP, EOPNOTSUPP, ENOTSOCK, EDESTADDRREQ, EMSGSIZE,
EPROTONOSUPPORT, EAFNOSUPPORT, EADDRINUSE, ENETDOWN, ENETUNREACH, ECONNRESET, EISCONN,
ENOTCONN, ETIMEDOUT, ECONNREFUSED, ENXIO, EINPROGRESS, EXDEV, ENOPROTOOPT, EDEADLK, ENOLCK,
];
ALL.into_iter().find(|&e| -(e as i64) == ret)
}
}
|