[wasi-common]: clean up error handling (#1253)

* Introduce WasiCtxBuilderError error type

`WasiCtxBuilderError` is the `wasi-common` client-facing error type
which is exclusively thrown when building a new `WasiCtx` instance.
As such, building such an instance should not require the client to
understand different WASI errno values as was assumed until now.

This commit is a first step at streamlining error handling in
`wasi-common` and makes way for the `wiggle` crate.

When adding the `WasiCtxBuilderError`, I've had to do two things of
notable importance:
1. I've removed a couple of `ok_or` calls in `WasiCtxBuilder::build`
   and replaced them with `unwrap`s, following the same pattern in
   different builder methods above. This is fine since we _always_
   operate on non-empty `Option`s in `WasiCtxBuilder` thus `unwrap`ing
   will never fail. On the other hand, this might be a good opportunity
   to rethink the structure of our builder, and how we good remove
   the said `Option`s especially since we always populate them with
   empty containers to begin with. I understand this is to make
   chaining of builder methods easier which take and return `&mut self`
   and the same applies to `WasiCtxBuilder::build(&mut self)` method,
   but perhaps it would more cleanly signal the intentions if we simply
   moved `WasiCtxBuilder` instance around. Food for thought!
2. Methods specific to determining rights of passed around `std::fs::File`
   objects when populating `WasiCtx` `FdEntry` entities now return
   `io::Error` directly so that we can reuse them in `WasiCtxBuilder` methods
   (returning `WasiCtxBuilderError` error type), and in syscalls
   (returning WASI errno).

* Return WasiError directly in syscalls

Also, removes `error::Error` type altogether. Now, `io::Error` and
related are automatically converted to their corresponding WASI
errno value encapsulated as `WasiError`.

While here, it made sense to me to move `WasiError` to `wasi` module
which will align itself well with the upcoming changes introduced
by `wiggle`. To different standard `Result` from WASI specific, I've
created a helper alias `WasiResult` also residing in `wasi` module.

* Update wig

* Add from ffi::NulError and pass context to NotADirectory

* Add dummy commit to test CI
This commit is contained in:
Jakub Konka
2020-03-09 22:58:55 +01:00
committed by GitHub
parent 963bf0e255
commit 773915b4bf
59 changed files with 1465 additions and 1552 deletions

View File

@@ -10,6 +10,115 @@ use wig::witx_wasi_types;
witx_wasi_types!("snapshot" "wasi_snapshot_preview1");
pub type WasiResult<T> = Result<T, WasiError>;
#[derive(Clone, Copy, Debug, thiserror::Error, Eq, PartialEq)]
#[repr(u16)]
#[error("{:?} ({})", self, strerror(*self as __wasi_errno_t))]
pub enum WasiError {
ESUCCESS = __WASI_ERRNO_SUCCESS,
E2BIG = __WASI_ERRNO_2BIG,
EACCES = __WASI_ERRNO_ACCES,
EADDRINUSE = __WASI_ERRNO_ADDRINUSE,
EADDRNOTAVAIL = __WASI_ERRNO_ADDRNOTAVAIL,
EAFNOSUPPORT = __WASI_ERRNO_AFNOSUPPORT,
EAGAIN = __WASI_ERRNO_AGAIN,
EALREADY = __WASI_ERRNO_ALREADY,
EBADF = __WASI_ERRNO_BADF,
EBADMSG = __WASI_ERRNO_BADMSG,
EBUSY = __WASI_ERRNO_BUSY,
ECANCELED = __WASI_ERRNO_CANCELED,
ECHILD = __WASI_ERRNO_CHILD,
ECONNABORTED = __WASI_ERRNO_CONNABORTED,
ECONNREFUSED = __WASI_ERRNO_CONNREFUSED,
ECONNRESET = __WASI_ERRNO_CONNRESET,
EDEADLK = __WASI_ERRNO_DEADLK,
EDESTADDRREQ = __WASI_ERRNO_DESTADDRREQ,
EDOM = __WASI_ERRNO_DOM,
EDQUOT = __WASI_ERRNO_DQUOT,
EEXIST = __WASI_ERRNO_EXIST,
EFAULT = __WASI_ERRNO_FAULT,
EFBIG = __WASI_ERRNO_FBIG,
EHOSTUNREACH = __WASI_ERRNO_HOSTUNREACH,
EIDRM = __WASI_ERRNO_IDRM,
EILSEQ = __WASI_ERRNO_ILSEQ,
EINPROGRESS = __WASI_ERRNO_INPROGRESS,
EINTR = __WASI_ERRNO_INTR,
EINVAL = __WASI_ERRNO_INVAL,
EIO = __WASI_ERRNO_IO,
EISCONN = __WASI_ERRNO_ISCONN,
EISDIR = __WASI_ERRNO_ISDIR,
ELOOP = __WASI_ERRNO_LOOP,
EMFILE = __WASI_ERRNO_MFILE,
EMLINK = __WASI_ERRNO_MLINK,
EMSGSIZE = __WASI_ERRNO_MSGSIZE,
EMULTIHOP = __WASI_ERRNO_MULTIHOP,
ENAMETOOLONG = __WASI_ERRNO_NAMETOOLONG,
ENETDOWN = __WASI_ERRNO_NETDOWN,
ENETRESET = __WASI_ERRNO_NETRESET,
ENETUNREACH = __WASI_ERRNO_NETUNREACH,
ENFILE = __WASI_ERRNO_NFILE,
ENOBUFS = __WASI_ERRNO_NOBUFS,
ENODEV = __WASI_ERRNO_NODEV,
ENOENT = __WASI_ERRNO_NOENT,
ENOEXEC = __WASI_ERRNO_NOEXEC,
ENOLCK = __WASI_ERRNO_NOLCK,
ENOLINK = __WASI_ERRNO_NOLINK,
ENOMEM = __WASI_ERRNO_NOMEM,
ENOMSG = __WASI_ERRNO_NOMSG,
ENOPROTOOPT = __WASI_ERRNO_NOPROTOOPT,
ENOSPC = __WASI_ERRNO_NOSPC,
ENOSYS = __WASI_ERRNO_NOSYS,
ENOTCONN = __WASI_ERRNO_NOTCONN,
ENOTDIR = __WASI_ERRNO_NOTDIR,
ENOTEMPTY = __WASI_ERRNO_NOTEMPTY,
ENOTRECOVERABLE = __WASI_ERRNO_NOTRECOVERABLE,
ENOTSOCK = __WASI_ERRNO_NOTSOCK,
ENOTSUP = __WASI_ERRNO_NOTSUP,
ENOTTY = __WASI_ERRNO_NOTTY,
ENXIO = __WASI_ERRNO_NXIO,
EOVERFLOW = __WASI_ERRNO_OVERFLOW,
EOWNERDEAD = __WASI_ERRNO_OWNERDEAD,
EPERM = __WASI_ERRNO_PERM,
EPIPE = __WASI_ERRNO_PIPE,
EPROTO = __WASI_ERRNO_PROTO,
EPROTONOSUPPORT = __WASI_ERRNO_PROTONOSUPPORT,
EPROTOTYPE = __WASI_ERRNO_PROTOTYPE,
ERANGE = __WASI_ERRNO_RANGE,
EROFS = __WASI_ERRNO_ROFS,
ESPIPE = __WASI_ERRNO_SPIPE,
ESRCH = __WASI_ERRNO_SRCH,
ESTALE = __WASI_ERRNO_STALE,
ETIMEDOUT = __WASI_ERRNO_TIMEDOUT,
ETXTBSY = __WASI_ERRNO_TXTBSY,
EXDEV = __WASI_ERRNO_XDEV,
ENOTCAPABLE = __WASI_ERRNO_NOTCAPABLE,
}
impl WasiError {
pub fn as_raw_errno(self) -> __wasi_errno_t {
self as __wasi_errno_t
}
}
impl From<std::convert::Infallible> for WasiError {
fn from(_err: std::convert::Infallible) -> Self {
unreachable!()
}
}
impl From<std::num::TryFromIntError> for WasiError {
fn from(_err: std::num::TryFromIntError) -> Self {
Self::EOVERFLOW
}
}
impl From<std::str::Utf8Error> for WasiError {
fn from(_err: std::str::Utf8Error) -> Self {
Self::EILSEQ
}
}
pub(crate) const RIGHTS_ALL: __wasi_rights_t = __WASI_RIGHTS_FD_DATASYNC
| __WASI_RIGHTS_FD_READ
| __WASI_RIGHTS_FD_SEEK