RustForge

rust-kernel

Rustbelt: a hobby x86_64 kernel written in Rust

rust-kernel / src / errno.rs
4529 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
79
80
81
//! 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
    EACCES = 13,       // permission denied (setpriority: only root may raise priority)
    EMLINK = 31,       // too many hard links to one file
    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; 54] = [
            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, EMLINK,
            EACCES,
        ];
        ALL.into_iter().find(|&e| -(e as i64) == ret)
    }
}