//! 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 { 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) } }