push the error types conversion all the way through
This commit is contained in:
@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use wasi_c2::{
|
use wasi_c2::{
|
||||||
dir::{ReaddirCursor, ReaddirEntity, WasiDir},
|
dir::{ReaddirCursor, ReaddirEntity, WasiDir},
|
||||||
file::{FdFlags, FileCaps, FileType, Filestat, OFlags, WasiFile},
|
file::{FdFlags, FileCaps, FileType, Filestat, OFlags, WasiFile},
|
||||||
Error,
|
Error, ErrorExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Dir(cap_std::fs::Dir);
|
pub struct Dir(cap_std::fs::Dir);
|
||||||
@@ -118,7 +118,10 @@ impl WasiDir for Dir {
|
|||||||
let meta = entry.metadata()?;
|
let meta = entry.metadata()?;
|
||||||
let inode = meta.ino();
|
let inode = meta.ino();
|
||||||
let filetype = filetype_from(&meta.file_type());
|
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()?;
|
let namelen = name.as_bytes().len().try_into()?;
|
||||||
Ok((filetype, inode, namelen, name))
|
Ok((filetype, inode, namelen, name))
|
||||||
}),
|
}),
|
||||||
@@ -189,7 +192,7 @@ impl WasiDir for Dir {
|
|||||||
let dest_dir = dest_dir
|
let dest_dir = dest_dir
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<Self>()
|
.downcast_ref::<Self>()
|
||||||
.ok_or(Error::NotCapable)?;
|
.ok_or(Error::badf().context("failed downcast to cap-std Dir"))?;
|
||||||
self.0
|
self.0
|
||||||
.rename(Path::new(src_path), &dest_dir.0, Path::new(dest_path))?;
|
.rename(Path::new(src_path), &dest_dir.0, Path::new(dest_path))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -204,7 +207,7 @@ impl WasiDir for Dir {
|
|||||||
let target_dir = target_dir
|
let target_dir = target_dir
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<Self>()
|
.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 src_path = Path::new(src_path);
|
||||||
let target_path = Path::new(target_path);
|
let target_path = Path::new(target_path);
|
||||||
self.0.hard_link(src_path, &target_dir.0, target_path)?;
|
self.0.hard_link(src_path, &target_dir.0, target_path)?;
|
||||||
|
|||||||
@@ -77,26 +77,26 @@ impl WasiFile for File {
|
|||||||
}
|
}
|
||||||
fn read_vectored(&self, bufs: &mut [io::IoSliceMut]) -> Result<u64, Error> {
|
fn read_vectored(&self, bufs: &mut [io::IoSliceMut]) -> Result<u64, Error> {
|
||||||
let n = self.0.read_vectored(bufs)?;
|
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> {
|
fn read_vectored_at(&self, bufs: &mut [io::IoSliceMut], offset: u64) -> Result<u64, Error> {
|
||||||
let n = self.0.read_vectored_at(bufs, offset)?;
|
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> {
|
fn write_vectored(&self, bufs: &[io::IoSlice]) -> Result<u64, Error> {
|
||||||
let n = self.0.write_vectored(bufs)?;
|
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> {
|
fn write_vectored_at(&self, bufs: &[io::IoSlice], offset: u64) -> Result<u64, Error> {
|
||||||
let n = self.0.write_vectored_at(bufs, offset)?;
|
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> {
|
fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> {
|
||||||
Ok(self.0.seek(pos)?)
|
Ok(self.0.seek(pos)?)
|
||||||
}
|
}
|
||||||
fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> {
|
fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> {
|
||||||
let n = self.0.peek(buf)?;
|
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> {
|
fn num_ready_bytes(&self) -> Result<u64, Error> {
|
||||||
Ok(self.0.num_ready_bytes()?)
|
Ok(self.0.num_ready_bytes()?)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use wasi_c2::{
|
|||||||
subscription::{RwEventFlags, Subscription},
|
subscription::{RwEventFlags, Subscription},
|
||||||
Poll, WasiSched,
|
Poll, WasiSched,
|
||||||
},
|
},
|
||||||
Error,
|
Error, ErrorExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
use poll::{PollFd, PollFlags};
|
use poll::{PollFd, PollFlags};
|
||||||
@@ -25,12 +25,16 @@ impl WasiSched for SyncSched {
|
|||||||
for s in poll.rw_subscriptions() {
|
for s in poll.rw_subscriptions() {
|
||||||
match s {
|
match s {
|
||||||
Subscription::Read(f) => {
|
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) });
|
pollfds.push(unsafe { PollFd::new(raw_fd, PollFlags::POLLIN) });
|
||||||
}
|
}
|
||||||
|
|
||||||
Subscription::Write(f) => {
|
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) });
|
pollfds.push(unsafe { PollFd::new(raw_fd, PollFlags::POLLOUT) });
|
||||||
}
|
}
|
||||||
Subscription::MonotonicClock { .. } => unreachable!(),
|
Subscription::MonotonicClock { .. } => unreachable!(),
|
||||||
@@ -45,7 +49,7 @@ impl WasiSched for SyncSched {
|
|||||||
.unwrap_or(Duration::from_secs(0));
|
.unwrap_or(Duration::from_secs(0));
|
||||||
(duration.as_millis() + 1) // XXX try always rounding up?
|
(duration.as_millis() + 1) // XXX try always rounding up?
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| Error::Overflow)?
|
.map_err(|_| Error::overflow().context("poll timeout"))?
|
||||||
} else {
|
} else {
|
||||||
libc::c_int::max_value()
|
libc::c_int::max_value()
|
||||||
};
|
};
|
||||||
@@ -78,9 +82,9 @@ impl WasiSched for SyncSched {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
if revents.contains(PollFlags::POLLNVAL) {
|
if revents.contains(PollFlags::POLLNVAL) {
|
||||||
rwsub.error(Error::Badf);
|
rwsub.error(Error::badf());
|
||||||
} else if revents.contains(PollFlags::POLLERR) {
|
} else if revents.contains(PollFlags::POLLERR) {
|
||||||
rwsub.error(Error::Io);
|
rwsub.error(Error::io());
|
||||||
} else if revents.contains(PollFlags::POLLHUP) {
|
} else if revents.contains(PollFlags::POLLHUP) {
|
||||||
rwsub.complete(nbytes, RwEventFlags::HANGUP);
|
rwsub.complete(nbytes, RwEventFlags::HANGUP);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use std::os::windows::io::{AsRawHandle, RawHandle};
|
|||||||
use unsafe_io::AsUnsafeFile;
|
use unsafe_io::AsUnsafeFile;
|
||||||
use wasi_c2::{
|
use wasi_c2::{
|
||||||
file::{FdFlags, FileType, Filestat, WasiFile},
|
file::{FdFlags, FileType, Filestat, WasiFile},
|
||||||
Error,
|
Error, ErrorExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Stdin(std::io::Stdin);
|
pub struct Stdin(std::io::Stdin);
|
||||||
@@ -40,7 +40,7 @@ impl WasiFile for Stdin {
|
|||||||
Ok(FdFlags::empty())
|
Ok(FdFlags::empty())
|
||||||
}
|
}
|
||||||
unsafe fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {
|
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> {
|
fn get_filestat(&self) -> Result<Filestat, Error> {
|
||||||
let meta = self.0.as_file_view().metadata()?;
|
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> {
|
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> {
|
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> {
|
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> {
|
fn read_vectored(&self, bufs: &mut [io::IoSliceMut]) -> Result<u64, Error> {
|
||||||
let n = self.0.as_file_view().read_vectored(bufs)?;
|
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> {
|
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> {
|
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> {
|
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> {
|
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> {
|
fn peek(&self, _buf: &mut [u8]) -> Result<u64, Error> {
|
||||||
Err(Error::Spipe)
|
Err(Error::seek_pipe())
|
||||||
}
|
}
|
||||||
fn set_times(
|
fn set_times(
|
||||||
&self,
|
&self,
|
||||||
@@ -132,7 +132,7 @@ macro_rules! wasi_file_write_impl {
|
|||||||
&self,
|
&self,
|
||||||
_fdflags: FdFlags,
|
_fdflags: FdFlags,
|
||||||
) -> Result<Box<dyn WasiFile>, Error> {
|
) -> Result<Box<dyn WasiFile>, Error> {
|
||||||
Err(Error::Badf)
|
Err(Error::badf())
|
||||||
}
|
}
|
||||||
fn get_filestat(&self) -> Result<Filestat, Error> {
|
fn get_filestat(&self) -> Result<Filestat, Error> {
|
||||||
let meta = self.0.as_file_view().metadata()?;
|
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> {
|
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> {
|
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> {
|
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> {
|
fn read_vectored(&self, _bufs: &mut [io::IoSliceMut]) -> Result<u64, Error> {
|
||||||
Err(Error::Badf)
|
Err(Error::badf())
|
||||||
}
|
}
|
||||||
fn read_vectored_at(
|
fn read_vectored_at(
|
||||||
&self,
|
&self,
|
||||||
_bufs: &mut [io::IoSliceMut],
|
_bufs: &mut [io::IoSliceMut],
|
||||||
_offset: u64,
|
_offset: u64,
|
||||||
) -> Result<u64, Error> {
|
) -> Result<u64, Error> {
|
||||||
Err(Error::Badf)
|
Err(Error::badf())
|
||||||
}
|
}
|
||||||
fn write_vectored(&self, bufs: &[io::IoSlice]) -> Result<u64, Error> {
|
fn write_vectored(&self, bufs: &[io::IoSlice]) -> Result<u64, Error> {
|
||||||
let n = self.0.as_file_view().write_vectored(bufs)?;
|
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> {
|
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> {
|
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> {
|
fn peek(&self, _buf: &mut [u8]) -> Result<u64, Error> {
|
||||||
Err(Error::Badf)
|
Err(Error::badf())
|
||||||
}
|
}
|
||||||
fn set_times(
|
fn set_times(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ pub enum ErrorKind {
|
|||||||
/// Errno::Inval: Invalid argument
|
/// Errno::Inval: Invalid argument
|
||||||
#[error("Inval: Invalid argument")]
|
#[error("Inval: Invalid argument")]
|
||||||
Inval,
|
Inval,
|
||||||
|
/// Errno::Io: I/O error
|
||||||
|
#[error("Io: I/O error")]
|
||||||
|
Io,
|
||||||
/// Errno::Nametoolong: Filename too long
|
/// Errno::Nametoolong: Filename too long
|
||||||
#[error("Nametoolong: Filename too long")]
|
#[error("Nametoolong: Filename too long")]
|
||||||
Nametoolong,
|
Nametoolong,
|
||||||
@@ -50,6 +53,7 @@ pub trait ErrorExt {
|
|||||||
fn exist() -> Self;
|
fn exist() -> Self;
|
||||||
fn illegal_byte_sequence() -> Self;
|
fn illegal_byte_sequence() -> Self;
|
||||||
fn invalid_argument() -> Self;
|
fn invalid_argument() -> Self;
|
||||||
|
fn io() -> Self;
|
||||||
fn name_too_long() -> Self;
|
fn name_too_long() -> Self;
|
||||||
fn not_dir() -> Self;
|
fn not_dir() -> Self;
|
||||||
fn not_supported() -> Self;
|
fn not_supported() -> Self;
|
||||||
@@ -75,6 +79,9 @@ impl ErrorExt for Error {
|
|||||||
fn invalid_argument() -> Self {
|
fn invalid_argument() -> Self {
|
||||||
ErrorKind::Inval.into()
|
ErrorKind::Inval.into()
|
||||||
}
|
}
|
||||||
|
fn io() -> Self {
|
||||||
|
ErrorKind::Io.into()
|
||||||
|
}
|
||||||
fn name_too_long() -> Self {
|
fn name_too_long() -> Self {
|
||||||
ErrorKind::Nametoolong.into()
|
ErrorKind::Nametoolong.into()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ impl From<ErrorKind> for types::Errno {
|
|||||||
ErrorKind::Exist => Errno::Exist,
|
ErrorKind::Exist => Errno::Exist,
|
||||||
ErrorKind::Ilseq => Errno::Ilseq,
|
ErrorKind::Ilseq => Errno::Ilseq,
|
||||||
ErrorKind::Inval => Errno::Inval,
|
ErrorKind::Inval => Errno::Inval,
|
||||||
|
ErrorKind::Io => Errno::Io,
|
||||||
ErrorKind::Nametoolong => Errno::Nametoolong,
|
ErrorKind::Nametoolong => Errno::Nametoolong,
|
||||||
ErrorKind::Notdir => Errno::Notdir,
|
ErrorKind::Notdir => Errno::Notdir,
|
||||||
ErrorKind::Notsup => Errno::Notsup,
|
ErrorKind::Notsup => Errno::Notsup,
|
||||||
@@ -141,9 +142,15 @@ impl TryFrom<std::io::Error> for types::Errno {
|
|||||||
libc::EOVERFLOW => Ok(types::Errno::Overflow),
|
libc::EOVERFLOW => Ok(types::Errno::Overflow),
|
||||||
libc::EILSEQ => Ok(types::Errno::Ilseq),
|
libc::EILSEQ => Ok(types::Errno::Ilseq),
|
||||||
libc::ENOTSUP => Ok(types::Errno::Notsup),
|
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")),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user