push the error types conversion all the way through

This commit is contained in:
Pat Hickey
2021-01-22 15:29:09 -08:00
parent 1d8070b734
commit 423973a8ea
6 changed files with 59 additions and 38 deletions

View File

@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
use wasi_c2::{
dir::{ReaddirCursor, ReaddirEntity, WasiDir},
file::{FdFlags, FileCaps, FileType, Filestat, OFlags, WasiFile},
Error,
Error, ErrorExt,
};
pub struct Dir(cap_std::fs::Dir);
@@ -118,7 +118,10 @@ impl WasiDir for Dir {
let meta = entry.metadata()?;
let inode = meta.ino();
let filetype = filetype_from(&meta.file_type());
let name = entry.file_name().into_string().map_err(|_| Error::Ilseq)?;
let name = entry
.file_name()
.into_string()
.map_err(|_| Error::illegal_byte_sequence().context("filename"))?;
let namelen = name.as_bytes().len().try_into()?;
Ok((filetype, inode, namelen, name))
}),
@@ -189,7 +192,7 @@ impl WasiDir for Dir {
let dest_dir = dest_dir
.as_any()
.downcast_ref::<Self>()
.ok_or(Error::NotCapable)?;
.ok_or(Error::badf().context("failed downcast to cap-std Dir"))?;
self.0
.rename(Path::new(src_path), &dest_dir.0, Path::new(dest_path))?;
Ok(())
@@ -204,7 +207,7 @@ impl WasiDir for Dir {
let target_dir = target_dir
.as_any()
.downcast_ref::<Self>()
.ok_or(Error::NotCapable)?;
.ok_or(Error::badf().context("failed downcast to cap-std Dir"))?;
let src_path = Path::new(src_path);
let target_path = Path::new(target_path);
self.0.hard_link(src_path, &target_dir.0, target_path)?;

View File

@@ -77,26 +77,26 @@ impl WasiFile for File {
}
fn read_vectored(&self, bufs: &mut [io::IoSliceMut]) -> Result<u64, Error> {
let n = self.0.read_vectored(bufs)?;
Ok(n.try_into().map_err(|_| Error::Overflow)?)
Ok(n.try_into()?)
}
fn read_vectored_at(&self, bufs: &mut [io::IoSliceMut], offset: u64) -> Result<u64, Error> {
let n = self.0.read_vectored_at(bufs, offset)?;
Ok(n.try_into().map_err(|_| Error::Overflow)?)
Ok(n.try_into()?)
}
fn write_vectored(&self, bufs: &[io::IoSlice]) -> Result<u64, Error> {
let n = self.0.write_vectored(bufs)?;
Ok(n.try_into().map_err(|_| Error::Overflow)?)
Ok(n.try_into()?)
}
fn write_vectored_at(&self, bufs: &[io::IoSlice], offset: u64) -> Result<u64, Error> {
let n = self.0.write_vectored_at(bufs, offset)?;
Ok(n.try_into().map_err(|_| Error::Overflow)?)
Ok(n.try_into()?)
}
fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> {
Ok(self.0.seek(pos)?)
}
fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> {
let n = self.0.peek(buf)?;
Ok(n.try_into().map_err(|_| Error::Overflow)?)
Ok(n.try_into()?)
}
fn num_ready_bytes(&self) -> Result<u64, Error> {
Ok(self.0.num_ready_bytes()?)

View File

@@ -8,7 +8,7 @@ use wasi_c2::{
subscription::{RwEventFlags, Subscription},
Poll, WasiSched,
},
Error,
Error, ErrorExt,
};
use poll::{PollFd, PollFlags};
@@ -25,12 +25,16 @@ impl WasiSched for SyncSched {
for s in poll.rw_subscriptions() {
match s {
Subscription::Read(f) => {
let raw_fd = wasi_file_raw_fd(f.file.deref()).ok_or(Error::Inval)?;
let raw_fd = wasi_file_raw_fd(f.file.deref()).ok_or(
Error::invalid_argument().context("read subscription fd downcast failed"),
)?;
pollfds.push(unsafe { PollFd::new(raw_fd, PollFlags::POLLIN) });
}
Subscription::Write(f) => {
let raw_fd = wasi_file_raw_fd(f.file.deref()).ok_or(Error::Inval)?;
let raw_fd = wasi_file_raw_fd(f.file.deref()).ok_or(
Error::invalid_argument().context("write subscription fd downcast failed"),
)?;
pollfds.push(unsafe { PollFd::new(raw_fd, PollFlags::POLLOUT) });
}
Subscription::MonotonicClock { .. } => unreachable!(),
@@ -45,7 +49,7 @@ impl WasiSched for SyncSched {
.unwrap_or(Duration::from_secs(0));
(duration.as_millis() + 1) // XXX try always rounding up?
.try_into()
.map_err(|_| Error::Overflow)?
.map_err(|_| Error::overflow().context("poll timeout"))?
} else {
libc::c_int::max_value()
};
@@ -78,9 +82,9 @@ impl WasiSched for SyncSched {
_ => unreachable!(),
};
if revents.contains(PollFlags::POLLNVAL) {
rwsub.error(Error::Badf);
rwsub.error(Error::badf());
} else if revents.contains(PollFlags::POLLERR) {
rwsub.error(Error::Io);
rwsub.error(Error::io());
} else if revents.contains(PollFlags::POLLHUP) {
rwsub.complete(nbytes, RwEventFlags::HANGUP);
} else {

View File

@@ -13,7 +13,7 @@ use std::os::windows::io::{AsRawHandle, RawHandle};
use unsafe_io::AsUnsafeFile;
use wasi_c2::{
file::{FdFlags, FileType, Filestat, WasiFile},
Error,
Error, ErrorExt,
};
pub struct Stdin(std::io::Stdin);
@@ -40,7 +40,7 @@ impl WasiFile for Stdin {
Ok(FdFlags::empty())
}
unsafe fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn get_filestat(&self) -> Result<Filestat, Error> {
let meta = self.0.as_file_view().metadata()?;
@@ -56,32 +56,32 @@ impl WasiFile for Stdin {
})
}
fn set_filestat_size(&self, _size: u64) -> Result<(), Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn advise(&self, _offset: u64, _len: u64, _advice: Advice) -> Result<(), Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn allocate(&self, _offset: u64, _len: u64) -> Result<(), Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn read_vectored(&self, bufs: &mut [io::IoSliceMut]) -> Result<u64, Error> {
let n = self.0.as_file_view().read_vectored(bufs)?;
Ok(n.try_into().map_err(|_| Error::Overflow)?)
Ok(n.try_into().map_err(|_| Error::range())?)
}
fn read_vectored_at(&self, _bufs: &mut [io::IoSliceMut], _offset: u64) -> Result<u64, Error> {
Err(Error::Spipe)
Err(Error::seek_pipe())
}
fn write_vectored(&self, _bufs: &[io::IoSlice]) -> Result<u64, Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn write_vectored_at(&self, _bufs: &[io::IoSlice], _offset: u64) -> Result<u64, Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn seek(&self, _pos: std::io::SeekFrom) -> Result<u64, Error> {
Err(Error::Spipe)
Err(Error::seek_pipe())
}
fn peek(&self, _buf: &mut [u8]) -> Result<u64, Error> {
Err(Error::Spipe)
Err(Error::seek_pipe())
}
fn set_times(
&self,
@@ -132,7 +132,7 @@ macro_rules! wasi_file_write_impl {
&self,
_fdflags: FdFlags,
) -> Result<Box<dyn WasiFile>, Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn get_filestat(&self) -> Result<Filestat, Error> {
let meta = self.0.as_file_view().metadata()?;
@@ -148,36 +148,36 @@ macro_rules! wasi_file_write_impl {
})
}
fn set_filestat_size(&self, _size: u64) -> Result<(), Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn advise(&self, _offset: u64, _len: u64, _advice: Advice) -> Result<(), Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn allocate(&self, _offset: u64, _len: u64) -> Result<(), Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn read_vectored(&self, _bufs: &mut [io::IoSliceMut]) -> Result<u64, Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn read_vectored_at(
&self,
_bufs: &mut [io::IoSliceMut],
_offset: u64,
) -> Result<u64, Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn write_vectored(&self, bufs: &[io::IoSlice]) -> Result<u64, Error> {
let n = self.0.as_file_view().write_vectored(bufs)?;
Ok(n.try_into().map_err(|_| Error::Overflow)?)
Ok(n.try_into().map_err(|c| Error::range().context(c))?)
}
fn write_vectored_at(&self, _bufs: &[io::IoSlice], _offset: u64) -> Result<u64, Error> {
Err(Error::Spipe)
Err(Error::seek_pipe())
}
fn seek(&self, _pos: std::io::SeekFrom) -> Result<u64, Error> {
Err(Error::Spipe)
Err(Error::seek_pipe())
}
fn peek(&self, _buf: &mut [u8]) -> Result<u64, Error> {
Err(Error::Badf)
Err(Error::badf())
}
fn set_times(
&self,

View File

@@ -21,6 +21,9 @@ pub enum ErrorKind {
/// Errno::Inval: Invalid argument
#[error("Inval: Invalid argument")]
Inval,
/// Errno::Io: I/O error
#[error("Io: I/O error")]
Io,
/// Errno::Nametoolong: Filename too long
#[error("Nametoolong: Filename too long")]
Nametoolong,
@@ -50,6 +53,7 @@ pub trait ErrorExt {
fn exist() -> Self;
fn illegal_byte_sequence() -> Self;
fn invalid_argument() -> Self;
fn io() -> Self;
fn name_too_long() -> Self;
fn not_dir() -> Self;
fn not_supported() -> Self;
@@ -75,6 +79,9 @@ impl ErrorExt for Error {
fn invalid_argument() -> Self {
ErrorKind::Inval.into()
}
fn io() -> Self {
ErrorKind::Io.into()
}
fn name_too_long() -> Self {
ErrorKind::Nametoolong.into()
}

View File

@@ -79,6 +79,7 @@ impl From<ErrorKind> for types::Errno {
ErrorKind::Exist => Errno::Exist,
ErrorKind::Ilseq => Errno::Ilseq,
ErrorKind::Inval => Errno::Inval,
ErrorKind::Io => Errno::Io,
ErrorKind::Nametoolong => Errno::Nametoolong,
ErrorKind::Notdir => Errno::Notdir,
ErrorKind::Notsup => Errno::Notsup,
@@ -141,9 +142,15 @@ impl TryFrom<std::io::Error> for types::Errno {
libc::EOVERFLOW => Ok(types::Errno::Overflow),
libc::EILSEQ => Ok(types::Errno::Ilseq),
libc::ENOTSUP => Ok(types::Errno::Notsup),
_ => Err(anyhow!(err).context("Unknown raw OS error")),
code => Err(anyhow!(err).context(format!("Unknown raw OS error: {}", code))),
},
None => match err.kind() {
std::io::ErrorKind::NotFound => Ok(types::Errno::Noent),
std::io::ErrorKind::PermissionDenied => Ok(types::Errno::Perm),
std::io::ErrorKind::AlreadyExists => Ok(types::Errno::Exist),
std::io::ErrorKind::InvalidInput => Ok(types::Errno::Ilseq),
k => Err(anyhow!(err).context(format!("No raw OS error. Unhandled kind: {:?}", k))),
},
None => Err(anyhow!(err).context("No raw OS error")),
}
}
}