Add yanix crate and replace nix with yanix in wasi-common (#649)
* Add yanix crate This commit adds `yanix` crate as a Unix dependency for `wasi-common`. `yanix` stands for Yet Another Nix crate and is exactly what the name suggests: a crate in the spirit of the `nix` crate, but which takes a different approach, using lower-level interfaces with less abstraction, so that it fits better with its main use case, implementation of WASI syscalls. * Replace nix with yanix crate Having introduced `yanix` crate as an in-house replacement for the `nix` crate, this commit makes the necessary changes to `wasi-common` to depend _only_ on `yanix` crate. * Address review comments * make `fd_dup` unsafe * rename `get_fd` to `get_fd_flags`, etc. * reuse `io::Error::last_os_error()` to get the last errno value * Address more comments * make all `fcntl` fns unsafe * adjust `wasi-common` impl appropriately * Make all fns operating on RawFd unsafe * Fix linux build * Address more comments
This commit is contained in:
227
crates/wasi-common/yanix/src/errno.rs
Normal file
227
crates/wasi-common/yanix/src/errno.rs
Normal file
@@ -0,0 +1,227 @@
|
||||
//! Errno-specific for different Unix platforms
|
||||
use crate::Result;
|
||||
use std::{fmt, io};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Error, PartialEq, Eq, Hash)]
|
||||
#[repr(i32)]
|
||||
pub enum Errno {
|
||||
EPERM = libc::EPERM,
|
||||
ENOENT = libc::ENOENT,
|
||||
ESRCH = libc::ESRCH,
|
||||
EINTR = libc::EINTR,
|
||||
EIO = libc::EIO,
|
||||
ENXIO = libc::ENXIO,
|
||||
E2BIG = libc::E2BIG,
|
||||
ENOEXEC = libc::ENOEXEC,
|
||||
EBADF = libc::EBADF,
|
||||
ECHILD = libc::ECHILD,
|
||||
EAGAIN = libc::EAGAIN,
|
||||
ENOMEM = libc::ENOMEM,
|
||||
EACCES = libc::EACCES,
|
||||
EFAULT = libc::EFAULT,
|
||||
EBUSY = libc::EBUSY,
|
||||
EEXIST = libc::EEXIST,
|
||||
EXDEV = libc::EXDEV,
|
||||
ENODEV = libc::ENODEV,
|
||||
ENOTDIR = libc::ENOTDIR,
|
||||
EISDIR = libc::EISDIR,
|
||||
EINVAL = libc::EINVAL,
|
||||
ENFILE = libc::ENFILE,
|
||||
EMFILE = libc::EMFILE,
|
||||
ENOTTY = libc::ENOTTY,
|
||||
ETXTBSY = libc::ETXTBSY,
|
||||
EFBIG = libc::EFBIG,
|
||||
ENOSPC = libc::ENOSPC,
|
||||
ESPIPE = libc::ESPIPE,
|
||||
EROFS = libc::EROFS,
|
||||
EMLINK = libc::EMLINK,
|
||||
EPIPE = libc::EPIPE,
|
||||
EDOM = libc::EDOM,
|
||||
ERANGE = libc::ERANGE,
|
||||
EDEADLK = libc::EDEADLK,
|
||||
ENAMETOOLONG = libc::ENAMETOOLONG,
|
||||
ENOLCK = libc::ENOLCK,
|
||||
ENOSYS = libc::ENOSYS,
|
||||
ENOTEMPTY = libc::ENOTEMPTY,
|
||||
ELOOP = libc::ELOOP,
|
||||
ENOMSG = libc::ENOMSG,
|
||||
EIDRM = libc::EIDRM,
|
||||
ENOLINK = libc::ENOLINK,
|
||||
EPROTO = libc::EPROTO,
|
||||
EMULTIHOP = libc::EMULTIHOP,
|
||||
EBADMSG = libc::EBADMSG,
|
||||
EOVERFLOW = libc::EOVERFLOW,
|
||||
EILSEQ = libc::EILSEQ,
|
||||
ENOTSOCK = libc::ENOTSOCK,
|
||||
EDESTADDRREQ = libc::EDESTADDRREQ,
|
||||
EMSGSIZE = libc::EMSGSIZE,
|
||||
EPROTOTYPE = libc::EPROTOTYPE,
|
||||
ENOPROTOOPT = libc::ENOPROTOOPT,
|
||||
EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
|
||||
EAFNOSUPPORT = libc::EAFNOSUPPORT,
|
||||
EADDRINUSE = libc::EADDRINUSE,
|
||||
EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
|
||||
ENETDOWN = libc::ENETDOWN,
|
||||
ENETUNREACH = libc::ENETUNREACH,
|
||||
ENETRESET = libc::ENETRESET,
|
||||
ECONNABORTED = libc::ECONNABORTED,
|
||||
ECONNRESET = libc::ECONNRESET,
|
||||
ENOBUFS = libc::ENOBUFS,
|
||||
EISCONN = libc::EISCONN,
|
||||
ENOTCONN = libc::ENOTCONN,
|
||||
ETIMEDOUT = libc::ETIMEDOUT,
|
||||
ECONNREFUSED = libc::ECONNREFUSED,
|
||||
EHOSTUNREACH = libc::EHOSTUNREACH,
|
||||
EALREADY = libc::EALREADY,
|
||||
EINPROGRESS = libc::EINPROGRESS,
|
||||
ESTALE = libc::ESTALE,
|
||||
EDQUOT = libc::EDQUOT,
|
||||
ECANCELED = libc::ECANCELED,
|
||||
EOWNERDEAD = libc::EOWNERDEAD,
|
||||
ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
|
||||
}
|
||||
|
||||
impl Errno {
|
||||
pub fn from_i32(err: i32) -> Self {
|
||||
match err {
|
||||
libc::EPERM => Self::EPERM,
|
||||
libc::ENOENT => Self::ENOENT,
|
||||
libc::ESRCH => Self::ESRCH,
|
||||
libc::EINTR => Self::EINTR,
|
||||
libc::EIO => Self::EIO,
|
||||
libc::ENXIO => Self::ENXIO,
|
||||
libc::E2BIG => Self::E2BIG,
|
||||
libc::ENOEXEC => Self::ENOEXEC,
|
||||
libc::EBADF => Self::EBADF,
|
||||
libc::ECHILD => Self::ECHILD,
|
||||
libc::EAGAIN => Self::EAGAIN,
|
||||
libc::ENOMEM => Self::ENOMEM,
|
||||
libc::EACCES => Self::EACCES,
|
||||
libc::EFAULT => Self::EFAULT,
|
||||
libc::EBUSY => Self::EBUSY,
|
||||
libc::EEXIST => Self::EEXIST,
|
||||
libc::EXDEV => Self::EXDEV,
|
||||
libc::ENODEV => Self::ENODEV,
|
||||
libc::ENOTDIR => Self::ENOTDIR,
|
||||
libc::EISDIR => Self::EISDIR,
|
||||
libc::EINVAL => Self::EINVAL,
|
||||
libc::ENFILE => Self::ENFILE,
|
||||
libc::EMFILE => Self::EMFILE,
|
||||
libc::ENOTTY => Self::ENOTTY,
|
||||
libc::ETXTBSY => Self::ETXTBSY,
|
||||
libc::EFBIG => Self::EFBIG,
|
||||
libc::ENOSPC => Self::ENOSPC,
|
||||
libc::ESPIPE => Self::ESPIPE,
|
||||
libc::EROFS => Self::EROFS,
|
||||
libc::EMLINK => Self::EMLINK,
|
||||
libc::EPIPE => Self::EPIPE,
|
||||
libc::EDOM => Self::EDOM,
|
||||
libc::ERANGE => Self::ERANGE,
|
||||
libc::EDEADLK => Self::EDEADLK,
|
||||
libc::ENAMETOOLONG => Self::ENAMETOOLONG,
|
||||
libc::ENOLCK => Self::ENOLCK,
|
||||
libc::ENOSYS => Self::ENOSYS,
|
||||
libc::ENOTEMPTY => Self::ENOTEMPTY,
|
||||
libc::ELOOP => Self::ELOOP,
|
||||
libc::ENOMSG => Self::ENOMSG,
|
||||
libc::EIDRM => Self::EIDRM,
|
||||
libc::ENOLINK => Self::ENOLINK,
|
||||
libc::EPROTO => Self::EPROTO,
|
||||
libc::EMULTIHOP => Self::EMULTIHOP,
|
||||
libc::EBADMSG => Self::EBADMSG,
|
||||
libc::EOVERFLOW => Self::EOVERFLOW,
|
||||
libc::EILSEQ => Self::EILSEQ,
|
||||
libc::ENOTSOCK => Self::ENOTSOCK,
|
||||
libc::EDESTADDRREQ => Self::EDESTADDRREQ,
|
||||
libc::EMSGSIZE => Self::EMSGSIZE,
|
||||
libc::EPROTOTYPE => Self::EPROTOTYPE,
|
||||
libc::ENOPROTOOPT => Self::ENOPROTOOPT,
|
||||
libc::EPROTONOSUPPORT => Self::EPROTONOSUPPORT,
|
||||
libc::EAFNOSUPPORT => Self::EAFNOSUPPORT,
|
||||
libc::EADDRINUSE => Self::EADDRINUSE,
|
||||
libc::EADDRNOTAVAIL => Self::EADDRNOTAVAIL,
|
||||
libc::ENETDOWN => Self::ENETDOWN,
|
||||
libc::ENETUNREACH => Self::ENETUNREACH,
|
||||
libc::ENETRESET => Self::ENETRESET,
|
||||
libc::ECONNABORTED => Self::ECONNABORTED,
|
||||
libc::ECONNRESET => Self::ECONNRESET,
|
||||
libc::ENOBUFS => Self::ENOBUFS,
|
||||
libc::EISCONN => Self::EISCONN,
|
||||
libc::ENOTCONN => Self::ENOTCONN,
|
||||
libc::ETIMEDOUT => Self::ETIMEDOUT,
|
||||
libc::ECONNREFUSED => Self::ECONNREFUSED,
|
||||
libc::EHOSTUNREACH => Self::EHOSTUNREACH,
|
||||
libc::EALREADY => Self::EALREADY,
|
||||
libc::EINPROGRESS => Self::EINPROGRESS,
|
||||
libc::ESTALE => Self::ESTALE,
|
||||
libc::EDQUOT => Self::EDQUOT,
|
||||
libc::ECANCELED => Self::ECANCELED,
|
||||
libc::EOWNERDEAD => Self::EOWNERDEAD,
|
||||
libc::ENOTRECOVERABLE => Self::ENOTRECOVERABLE,
|
||||
other => {
|
||||
log::warn!("Unknown errno: {}", other);
|
||||
Self::ENOSYS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn last() -> Self {
|
||||
let errno = io::Error::last_os_error()
|
||||
.raw_os_error()
|
||||
.unwrap_or(libc::ENOSYS);
|
||||
Self::from_i32(errno)
|
||||
}
|
||||
|
||||
pub fn from_success_code<T: IsZero>(t: T) -> Result<()> {
|
||||
if t.is_zero() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Self::last().into())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_result<T: IsMinusOne>(t: T) -> Result<T> {
|
||||
if t.is_minus_one() {
|
||||
Err(Self::last().into())
|
||||
} else {
|
||||
Ok(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Errno {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Errno code: {}", self)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait IsZero {
|
||||
fn is_zero(&self) -> bool;
|
||||
}
|
||||
|
||||
macro_rules! impl_is_zero {
|
||||
($($t:ident)*) => ($(impl IsZero for $t {
|
||||
fn is_zero(&self) -> bool {
|
||||
*self == 0
|
||||
}
|
||||
})*)
|
||||
}
|
||||
|
||||
impl_is_zero! { i32 i64 isize }
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait IsMinusOne {
|
||||
fn is_minus_one(&self) -> bool;
|
||||
}
|
||||
|
||||
macro_rules! impl_is_minus_one {
|
||||
($($t:ident)*) => ($(impl IsMinusOne for $t {
|
||||
fn is_minus_one(&self) -> bool {
|
||||
*self == -1
|
||||
}
|
||||
})*)
|
||||
}
|
||||
|
||||
impl_is_minus_one! { i32 i64 isize }
|
||||
Reference in New Issue
Block a user