wasi-common: instead of panicking, use an Error::Unsupported that Traps
This commit is contained in:
@@ -17,6 +17,10 @@ pub enum Error {
|
|||||||
#[error("GetRandom: {0}")]
|
#[error("GetRandom: {0}")]
|
||||||
GetRandom(#[from] getrandom::Error),
|
GetRandom(#[from] getrandom::Error),
|
||||||
|
|
||||||
|
/// Some corners of the WASI standard are unsupported.
|
||||||
|
#[error("Unsupported: {0}")]
|
||||||
|
Unsupported(&'static str),
|
||||||
|
|
||||||
/// The host OS may return an io error that doesn't match one of the
|
/// The host OS may return an io error that doesn't match one of the
|
||||||
/// wasi errno variants we expect. We do not expose the details of this
|
/// wasi errno variants we expect. We do not expose the details of this
|
||||||
/// error to the user.
|
/// error to the user.
|
||||||
|
|||||||
@@ -724,7 +724,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn proc_raise(&self, _sig: types::Signal) -> Result<()> {
|
fn proc_raise(&self, _sig: types::Signal) -> Result<()> {
|
||||||
unimplemented!("proc_raise")
|
Err(Error::Unsupported("proc_raise"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sched_yield(&self) -> Result<()> {
|
fn sched_yield(&self) -> Result<()> {
|
||||||
@@ -744,7 +744,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
_ri_data: &types::IovecArray<'_>,
|
_ri_data: &types::IovecArray<'_>,
|
||||||
_ri_flags: types::Riflags,
|
_ri_flags: types::Riflags,
|
||||||
) -> Result<(types::Size, types::Roflags)> {
|
) -> Result<(types::Size, types::Roflags)> {
|
||||||
unimplemented!("sock_recv")
|
Err(Error::Unsupported("sock_recv"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sock_send(
|
fn sock_send(
|
||||||
@@ -753,11 +753,11 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
_si_data: &types::CiovecArray<'_>,
|
_si_data: &types::CiovecArray<'_>,
|
||||||
_si_flags: types::Siflags,
|
_si_flags: types::Siflags,
|
||||||
) -> Result<types::Size> {
|
) -> Result<types::Size> {
|
||||||
unimplemented!("sock_send")
|
Err(Error::Unsupported("sock_send"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sock_shutdown(&self, _fd: types::Fd, _how: types::Sdflags) -> Result<()> {
|
fn sock_shutdown(&self, _fd: types::Fd, _how: types::Sdflags) -> Result<()> {
|
||||||
unimplemented!("sock_shutdown")
|
Err(Error::Unsupported("sock_shutdown"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,7 +804,7 @@ impl WasiCtx {
|
|||||||
Err(error) => {
|
Err(error) => {
|
||||||
events.push(types::Event {
|
events.push(types::Event {
|
||||||
userdata: subscription.userdata,
|
userdata: subscription.userdata,
|
||||||
error: error.into(),
|
error: error.try_into().expect("non-trapping error"),
|
||||||
type_: types::Eventtype::FdRead,
|
type_: types::Eventtype::FdRead,
|
||||||
fd_readwrite: types::EventFdReadwrite {
|
fd_readwrite: types::EventFdReadwrite {
|
||||||
nbytes: 0,
|
nbytes: 0,
|
||||||
@@ -830,7 +830,7 @@ impl WasiCtx {
|
|||||||
Err(error) => {
|
Err(error) => {
|
||||||
events.push(types::Event {
|
events.push(types::Event {
|
||||||
userdata: subscription.userdata,
|
userdata: subscription.userdata,
|
||||||
error: error.into(),
|
error: error.try_into().expect("non-trapping error"),
|
||||||
type_: types::Eventtype::FdWrite,
|
type_: types::Eventtype::FdWrite,
|
||||||
fd_readwrite: types::EventFdReadwrite {
|
fd_readwrite: types::EventFdReadwrite {
|
||||||
nbytes: 0,
|
nbytes: 0,
|
||||||
|
|||||||
@@ -25,13 +25,14 @@ impl types::GuestErrorConversion for WasiCtx {
|
|||||||
impl types::UserErrorConversion for WasiCtx {
|
impl types::UserErrorConversion for WasiCtx {
|
||||||
fn errno_from_error(&self, e: Error) -> Result<Errno, wiggle::Trap> {
|
fn errno_from_error(&self, e: Error) -> Result<Errno, wiggle::Trap> {
|
||||||
tracing::debug!("Error: {:?}", e);
|
tracing::debug!("Error: {:?}", e);
|
||||||
Ok(e.into())
|
e.try_into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for Errno {
|
impl TryFrom<Error> for Errno {
|
||||||
fn from(e: Error) -> Errno {
|
type Error = wiggle::Trap;
|
||||||
types_new::Errno::from(e).into()
|
fn try_from(e: Error) -> Result<Errno, wiggle::Trap> {
|
||||||
|
Ok(types_new::Errno::try_from(e)?.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ fn handle_fd_event(
|
|||||||
let output_event = if revents.contains(PollFlags::POLLNVAL) {
|
let output_event = if revents.contains(PollFlags::POLLNVAL) {
|
||||||
Event {
|
Event {
|
||||||
userdata: fd_event.userdata,
|
userdata: fd_event.userdata,
|
||||||
error: Error::Badf.into(),
|
error: Error::Badf.try_into().unwrap(),
|
||||||
type_: fd_event.r#type,
|
type_: fd_event.r#type,
|
||||||
fd_readwrite: EventFdReadwrite {
|
fd_readwrite: EventFdReadwrite {
|
||||||
nbytes: 0,
|
nbytes: 0,
|
||||||
@@ -127,7 +127,7 @@ fn handle_fd_event(
|
|||||||
} else if revents.contains(PollFlags::POLLERR) {
|
} else if revents.contains(PollFlags::POLLERR) {
|
||||||
Event {
|
Event {
|
||||||
userdata: fd_event.userdata,
|
userdata: fd_event.userdata,
|
||||||
error: Error::Io.into(),
|
error: Error::Io.try_into().unwrap(),
|
||||||
type_: fd_event.r#type,
|
type_: fd_event.r#type,
|
||||||
fd_readwrite: EventFdReadwrite {
|
fd_readwrite: EventFdReadwrite {
|
||||||
nbytes: 0,
|
nbytes: 0,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::{Error, WasiCtx};
|
use crate::{Error, WasiCtx};
|
||||||
|
use std::convert::{TryFrom, TryInto};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
wiggle::from_witx!({
|
wiggle::from_witx!({
|
||||||
@@ -25,45 +26,49 @@ impl types::GuestErrorConversion for WasiCtx {
|
|||||||
impl types::UserErrorConversion for WasiCtx {
|
impl types::UserErrorConversion for WasiCtx {
|
||||||
fn errno_from_error(&self, e: Error) -> Result<Errno, wiggle::Trap> {
|
fn errno_from_error(&self, e: Error) -> Result<Errno, wiggle::Trap> {
|
||||||
debug!("Error: {:?}", e);
|
debug!("Error: {:?}", e);
|
||||||
Ok(e.into())
|
e.try_into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for Errno {
|
impl TryFrom<Error> for Errno {
|
||||||
fn from(e: Error) -> Errno {
|
type Error = wiggle::Trap;
|
||||||
|
fn try_from(e: Error) -> Result<Errno, wiggle::Trap> {
|
||||||
match e {
|
match e {
|
||||||
Error::Guest(e) => e.into(),
|
Error::Guest(e) => Ok(e.into()),
|
||||||
Error::TryFromInt(_) => Errno::Overflow,
|
Error::TryFromInt(_) => Ok(Errno::Overflow),
|
||||||
Error::Utf8(_) => Errno::Ilseq,
|
Error::Utf8(_) => Ok(Errno::Ilseq),
|
||||||
Error::UnexpectedIo(_) => Errno::Io,
|
Error::UnexpectedIo(_) => Ok(Errno::Io),
|
||||||
Error::GetRandom(_) => Errno::Io,
|
Error::GetRandom(_) => Ok(Errno::Io),
|
||||||
Error::TooBig => Errno::TooBig,
|
Error::TooBig => Ok(Errno::TooBig),
|
||||||
Error::Acces => Errno::Acces,
|
Error::Acces => Ok(Errno::Acces),
|
||||||
Error::Badf => Errno::Badf,
|
Error::Badf => Ok(Errno::Badf),
|
||||||
Error::Busy => Errno::Busy,
|
Error::Busy => Ok(Errno::Busy),
|
||||||
Error::Exist => Errno::Exist,
|
Error::Exist => Ok(Errno::Exist),
|
||||||
Error::Fault => Errno::Fault,
|
Error::Fault => Ok(Errno::Fault),
|
||||||
Error::Fbig => Errno::Fbig,
|
Error::Fbig => Ok(Errno::Fbig),
|
||||||
Error::Ilseq => Errno::Ilseq,
|
Error::Ilseq => Ok(Errno::Ilseq),
|
||||||
Error::Inval => Errno::Inval,
|
Error::Inval => Ok(Errno::Inval),
|
||||||
Error::Io => Errno::Io,
|
Error::Io => Ok(Errno::Io),
|
||||||
Error::Isdir => Errno::Isdir,
|
Error::Isdir => Ok(Errno::Isdir),
|
||||||
Error::Loop => Errno::Loop,
|
Error::Loop => Ok(Errno::Loop),
|
||||||
Error::Mfile => Errno::Mfile,
|
Error::Mfile => Ok(Errno::Mfile),
|
||||||
Error::Mlink => Errno::Mlink,
|
Error::Mlink => Ok(Errno::Mlink),
|
||||||
Error::Nametoolong => Errno::Nametoolong,
|
Error::Nametoolong => Ok(Errno::Nametoolong),
|
||||||
Error::Nfile => Errno::Nfile,
|
Error::Nfile => Ok(Errno::Nfile),
|
||||||
Error::Noent => Errno::Noent,
|
Error::Noent => Ok(Errno::Noent),
|
||||||
Error::Nomem => Errno::Nomem,
|
Error::Nomem => Ok(Errno::Nomem),
|
||||||
Error::Nospc => Errno::Nospc,
|
Error::Nospc => Ok(Errno::Nospc),
|
||||||
Error::Notdir => Errno::Notdir,
|
Error::Notdir => Ok(Errno::Notdir),
|
||||||
Error::Notempty => Errno::Notempty,
|
Error::Notempty => Ok(Errno::Notempty),
|
||||||
Error::Notsup => Errno::Notsup,
|
Error::Notsup => Ok(Errno::Notsup),
|
||||||
Error::Overflow => Errno::Overflow,
|
Error::Overflow => Ok(Errno::Overflow),
|
||||||
Error::Pipe => Errno::Pipe,
|
Error::Pipe => Ok(Errno::Pipe),
|
||||||
Error::Perm => Errno::Perm,
|
Error::Perm => Ok(Errno::Perm),
|
||||||
Error::Spipe => Errno::Spipe,
|
Error::Spipe => Ok(Errno::Spipe),
|
||||||
Error::Notcapable => Errno::Notcapable,
|
Error::Notcapable => Ok(Errno::Notcapable),
|
||||||
|
Error::Unsupported(feature) => {
|
||||||
|
Err(wiggle::Trap::String(format!("unsupported: {}", feature)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,8 +85,8 @@ impl From<wiggle::GuestError> for Errno {
|
|||||||
PtrBorrowed { .. } => Self::Fault,
|
PtrBorrowed { .. } => Self::Fault,
|
||||||
InvalidUtf8 { .. } => Self::Ilseq,
|
InvalidUtf8 { .. } => Self::Ilseq,
|
||||||
TryFromIntError { .. } => Self::Overflow,
|
TryFromIntError { .. } => Self::Overflow,
|
||||||
InFunc { .. } => Self::Inval,
|
InFunc { err, .. } => Errno::from(*err),
|
||||||
InDataField { .. } => Self::Inval,
|
InDataField { err, .. } => Errno::from(*err),
|
||||||
SliceLengthsDiffer { .. } => Self::Fault,
|
SliceLengthsDiffer { .. } => Self::Fault,
|
||||||
BorrowCheckerOutOfHandles { .. } => Self::Fault,
|
BorrowCheckerOutOfHandles { .. } => Self::Fault,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user