diff --git a/host/src/command.rs b/host/src/command.rs index b4958944..63d61323 100644 --- a/host/src/command.rs +++ b/host/src/command.rs @@ -6,6 +6,7 @@ pub mod wasi { world: "command", tracing: true, async: true, + trappable_error_type: { "filesystem"::"error-code": Error } }); } diff --git a/host/src/filesystem.rs b/host/src/filesystem.rs index 35d301eb..9a39424e 100644 --- a/host/src/filesystem.rs +++ b/host/src/filesystem.rs @@ -2,7 +2,8 @@ use crate::command::wasi; use crate::command::wasi::streams::{InputStream, OutputStream}; -use crate::{HostResult, WasiCtx}; +use crate::WasiCtx; +use anyhow::anyhow; use std::{ io::{IoSlice, IoSliceMut}, ops::Deref, @@ -15,63 +16,63 @@ use wasi_common::{ WasiDir, WasiFile, }; -fn convert(error: wasi_common::Error) -> anyhow::Error { - if let Some(errno) = error.downcast_ref() { +impl From for wasi::filesystem::Error { + fn from(error: wasi_common::Error) -> wasi::filesystem::Error { use wasi::filesystem::ErrorCode; use wasi_common::Errno::*; - - match errno { - Acces => ErrorCode::Access, - Again => ErrorCode::WouldBlock, - Already => ErrorCode::Already, - Badf => ErrorCode::BadDescriptor, - Busy => ErrorCode::Busy, - Deadlk => ErrorCode::Deadlock, - Dquot => ErrorCode::Quota, - Exist => ErrorCode::Exist, - Fbig => ErrorCode::FileTooLarge, - Ilseq => ErrorCode::IllegalByteSequence, - Inprogress => ErrorCode::InProgress, - Intr => ErrorCode::Interrupted, - Inval => ErrorCode::Invalid, - Io => ErrorCode::Io, - Isdir => ErrorCode::IsDirectory, - Loop => ErrorCode::Loop, - Mlink => ErrorCode::TooManyLinks, - Msgsize => ErrorCode::MessageSize, - Nametoolong => ErrorCode::NameTooLong, - Nodev => ErrorCode::NoDevice, - Noent => ErrorCode::NoEntry, - Nolck => ErrorCode::NoLock, - Nomem => ErrorCode::InsufficientMemory, - Nospc => ErrorCode::InsufficientSpace, - Nosys => ErrorCode::Unsupported, - Notdir => ErrorCode::NotDirectory, - Notempty => ErrorCode::NotEmpty, - Notrecoverable => ErrorCode::NotRecoverable, - Notsup => ErrorCode::Unsupported, - Notty => ErrorCode::NoTty, - Nxio => ErrorCode::NoSuchDevice, - Overflow => ErrorCode::Overflow, - Perm => ErrorCode::NotPermitted, - Pipe => ErrorCode::Pipe, - Rofs => ErrorCode::ReadOnly, - Spipe => ErrorCode::InvalidSeek, - Txtbsy => ErrorCode::TextFileBusy, - Xdev => ErrorCode::CrossDevice, - Success | Notsock | Proto | Protonosupport | Prototype | TooBig | Notconn => { - return error.into(); - } - Addrinuse | Addrnotavail | Afnosupport | Badmsg | Canceled | Connaborted - | Connrefused | Connreset | Destaddrreq | Fault | Hostunreach | Idrm | Isconn - | Mfile | Multihop | Netdown | Netreset | Netunreach | Nfile | Nobufs | Noexec - | Nolink | Nomsg | Noprotoopt | Ownerdead | Range | Srch | Stale | Timedout => { - panic!("Unexpected errno: {:?}", errno); + if let Some(errno) = error.downcast_ref() { + match errno { + Acces => ErrorCode::Access.into(), + Again => ErrorCode::WouldBlock.into(), + Already => ErrorCode::Already.into(), + Badf => ErrorCode::BadDescriptor.into(), + Busy => ErrorCode::Busy.into(), + Deadlk => ErrorCode::Deadlock.into(), + Dquot => ErrorCode::Quota.into(), + Exist => ErrorCode::Exist.into(), + Fbig => ErrorCode::FileTooLarge.into(), + Ilseq => ErrorCode::IllegalByteSequence.into(), + Inprogress => ErrorCode::InProgress.into(), + Intr => ErrorCode::Interrupted.into(), + Inval => ErrorCode::Invalid.into(), + Io => ErrorCode::Io.into(), + Isdir => ErrorCode::IsDirectory.into(), + Loop => ErrorCode::Loop.into(), + Mlink => ErrorCode::TooManyLinks.into(), + Msgsize => ErrorCode::MessageSize.into(), + Nametoolong => ErrorCode::NameTooLong.into(), + Nodev => ErrorCode::NoDevice.into(), + Noent => ErrorCode::NoEntry.into(), + Nolck => ErrorCode::NoLock.into(), + Nomem => ErrorCode::InsufficientMemory.into(), + Nospc => ErrorCode::InsufficientSpace.into(), + Nosys => ErrorCode::Unsupported.into(), + Notdir => ErrorCode::NotDirectory.into(), + Notempty => ErrorCode::NotEmpty.into(), + Notrecoverable => ErrorCode::NotRecoverable.into(), + Notsup => ErrorCode::Unsupported.into(), + Notty => ErrorCode::NoTty.into(), + Nxio => ErrorCode::NoSuchDevice.into(), + Overflow => ErrorCode::Overflow.into(), + Perm => ErrorCode::NotPermitted.into(), + Pipe => ErrorCode::Pipe.into(), + Rofs => ErrorCode::ReadOnly.into(), + Spipe => ErrorCode::InvalidSeek.into(), + Txtbsy => ErrorCode::TextFileBusy.into(), + Xdev => ErrorCode::CrossDevice.into(), + Success | Notsock | Proto | Protonosupport | Prototype | TooBig | Notconn => { + wasi::filesystem::Error::trap(anyhow!(error)) + } + Addrinuse | Addrnotavail | Afnosupport | Badmsg | Canceled | Connaborted + | Connrefused | Connreset | Destaddrreq | Fault | Hostunreach | Idrm | Isconn + | Mfile | Multihop | Netdown | Netreset | Netunreach | Nfile | Nobufs | Noexec + | Nolink | Nomsg | Noprotoopt | Ownerdead | Range | Srch | Stale | Timedout => { + wasi::filesystem::Error::trap(anyhow!("Unexpected errno: {:?}", errno)) + } } + } else { + wasi::filesystem::Error::trap(anyhow!(error)) } - .into() - } else { - error.into() } } @@ -212,33 +213,21 @@ impl wasi::filesystem::Host for WasiCtx { offset: wasi::filesystem::Filesize, len: wasi::filesystem::Filesize, advice: wasi::filesystem::Advice, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { - let f = self.table_mut().get_file_mut(fd).map_err(convert)?; - f.advise(offset, len, advice.into()) - .await - .map_err(convert)?; - Ok(Ok(())) + ) -> Result<(), wasi::filesystem::Error> { + let f = self.table_mut().get_file_mut(fd)?; + f.advise(offset, len, advice.into()).await?; + Ok(()) } async fn sync_data( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { let table = self.table(); if table.is::>(fd) { - Ok(Ok(table - .get_file(fd) - .map_err(convert)? - .datasync() - .await - .map_err(convert)?)) + Ok(table.get_file(fd)?.datasync().await?) } else if table.is::>(fd) { - Ok(Ok(table - .get_dir(fd) - .map_err(convert)? - .datasync() - .await - .map_err(convert)?)) + Ok(table.get_dir(fd)?.datasync().await?) } else { Err(wasi::filesystem::ErrorCode::BadDescriptor.into()) } @@ -247,24 +236,12 @@ impl wasi::filesystem::Host for WasiCtx { async fn get_flags( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult { + ) -> Result { let table = self.table(); if table.is::>(fd) { - Ok(Ok(table - .get_file(fd) - .map_err(convert)? - .get_fdflags() - .await - .map_err(convert)? - .into())) + Ok(table.get_file(fd)?.get_fdflags().await?.into()) } else if table.is::>(fd) { - Ok(Ok(table - .get_dir(fd) - .map_err(convert)? - .get_fdflags() - .await - .map_err(convert)? - .into())) + Ok(table.get_dir(fd)?.get_fdflags().await?.into()) } else { Err(wasi::filesystem::ErrorCode::BadDescriptor.into()) } @@ -273,18 +250,12 @@ impl wasi::filesystem::Host for WasiCtx { async fn get_type( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult { + ) -> Result { let table = self.table(); if table.is::>(fd) { - Ok(Ok(table - .get_file(fd) - .map_err(convert)? - .get_filetype() - .await - .map_err(convert)? - .into())) + Ok(table.get_file(fd)?.get_filetype().await?.into()) } else if table.is::>(fd) { - Ok(Ok(wasi::filesystem::DescriptorType::Directory)) + Ok(wasi::filesystem::DescriptorType::Directory) } else { Err(wasi::filesystem::ErrorCode::BadDescriptor.into()) } @@ -294,7 +265,7 @@ impl wasi::filesystem::Host for WasiCtx { &mut self, fd: wasi::filesystem::Descriptor, flags: wasi::filesystem::DescriptorFlags, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { // FIXME Err(wasi::filesystem::ErrorCode::Unsupported.into()) } @@ -303,10 +274,10 @@ impl wasi::filesystem::Host for WasiCtx { &mut self, fd: wasi::filesystem::Descriptor, size: wasi::filesystem::Filesize, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { - let f = self.table_mut().get_file_mut(fd).map_err(convert)?; - f.set_filestat_size(size).await.map_err(convert)?; - Ok(Ok(())) + ) -> Result<(), wasi::filesystem::Error> { + let f = self.table_mut().get_file_mut(fd)?; + f.set_filestat_size(size).await?; + Ok(()) } async fn set_times( @@ -314,25 +285,23 @@ impl wasi::filesystem::Host for WasiCtx { fd: wasi::filesystem::Descriptor, atim: wasi::filesystem::NewTimestamp, mtim: wasi::filesystem::NewTimestamp, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { let atim = system_time_spec_from_timestamp(atim); let mtim = system_time_spec_from_timestamp(mtim); let table = self.table_mut(); if table.is::>(fd) { - Ok(Ok(table + Ok(table .get_file_mut(fd) .expect("checked entry is a file") .set_times(atim, mtim) - .await - .map_err(convert)?)) + .await?) } else if table.is::>(fd) { - Ok(Ok(table + Ok(table .get_dir(fd) .expect("checked entry is a dir") .set_times(".", atim, mtim, false) - .await - .map_err(convert)?)) + .await?) } else { Err(wasi::filesystem::ErrorCode::BadDescriptor.into()) } @@ -343,19 +312,22 @@ impl wasi::filesystem::Host for WasiCtx { fd: wasi::filesystem::Descriptor, len: wasi::filesystem::Filesize, offset: wasi::filesystem::Filesize, - ) -> HostResult<(Vec, bool), wasi::filesystem::ErrorCode> { - let f = self.table_mut().get_file_mut(fd).map_err(convert)?; + ) -> Result<(Vec, bool), wasi::filesystem::Error> { + let f = self.table_mut().get_file_mut(fd)?; let mut buffer = vec![0; len.try_into().unwrap_or(usize::MAX)]; let (bytes_read, end) = f .read_vectored_at(&mut [IoSliceMut::new(&mut buffer)], offset) - .await - .map_err(convert)?; + .await?; - buffer.truncate(bytes_read.try_into().unwrap()); + buffer.truncate( + bytes_read + .try_into() + .expect("bytes read into memory as u64 fits in usize"), + ); - Ok(Ok((buffer, end))) + Ok((buffer, end)) } async fn write( @@ -363,65 +335,52 @@ impl wasi::filesystem::Host for WasiCtx { fd: wasi::filesystem::Descriptor, buf: Vec, offset: wasi::filesystem::Filesize, - ) -> HostResult { - let f = self.table_mut().get_file_mut(fd).map_err(convert)?; + ) -> Result { + let f = self.table_mut().get_file_mut(fd)?; - let bytes_written = f - .write_vectored_at(&[IoSlice::new(&buf)], offset) - .await - .map_err(convert)?; + let bytes_written = f.write_vectored_at(&[IoSlice::new(&buf)], offset).await?; - Ok(Ok( - wasi::filesystem::Filesize::try_from(bytes_written).unwrap() - )) + Ok(wasi::filesystem::Filesize::try_from(bytes_written).expect("usize fits in Filesize")) } async fn read_directory( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult { + ) -> Result { let iterator = self .table() - .get_dir(fd) - .map_err(convert)? + .get_dir(fd)? .readdir(ReaddirCursor::from(0)) - .await - .map_err(convert)?; + .await?; - self.table_mut() - .push(Box::new(Mutex::new(iterator))) - .map(Ok) - .map_err(convert) + Ok(self.table_mut().push(Box::new(Mutex::new(iterator)))?) } async fn read_directory_entry( &mut self, stream: wasi::filesystem::DirectoryEntryStream, - ) -> HostResult, wasi::filesystem::ErrorCode> { + ) -> Result, wasi::filesystem::Error> { let entity = self .table() - .get::>(stream) - .map_err(convert)? + .get::>(stream)? .lock() - .unwrap() + .expect("readdir iterator is lockable") .next() - .transpose() - .map_err(convert)?; + .transpose()?; - Ok(Ok(entity.map(|e| wasi::filesystem::DirectoryEntry { + Ok(entity.map(|e| wasi::filesystem::DirectoryEntry { inode: Some(e.inode), type_: e.filetype.into(), name: e.name, - }))) + })) } async fn drop_directory_entry_stream( &mut self, stream: wasi::filesystem::DirectoryEntryStream, ) -> anyhow::Result<()> { - self.table_mut() - .delete::>(stream) - .map_err(convert)?; + // Trap if deletion is not possible: + self.table_mut().delete::>(stream)?; Ok(()) } @@ -429,22 +388,12 @@ impl wasi::filesystem::Host for WasiCtx { async fn sync( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { let table = self.table(); if table.is::>(fd) { - Ok(Ok(table - .get_file(fd) - .map_err(convert)? - .sync() - .await - .map_err(convert)?)) + Ok(table.get_file(fd)?.sync().await?) } else if table.is::>(fd) { - Ok(Ok(table - .get_dir(fd) - .map_err(convert)? - .sync() - .await - .map_err(convert)?)) + Ok(table.get_dir(fd)?.sync().await?) } else { Err(wasi::filesystem::ErrorCode::BadDescriptor.into()) } @@ -454,37 +403,20 @@ impl wasi::filesystem::Host for WasiCtx { &mut self, fd: wasi::filesystem::Descriptor, path: String, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { let table = self.table(); - Ok(Ok(table - .get_dir(fd) - .map_err(convert)? - .create_dir(&path) - .await - .map_err(convert)?)) + Ok(table.get_dir(fd)?.create_dir(&path).await?) } async fn stat( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult { + ) -> Result { let table = self.table(); if table.is::>(fd) { - Ok(Ok(table - .get_file(fd) - .map_err(convert)? - .get_filestat() - .await - .map_err(convert)? - .into())) + Ok(table.get_file(fd)?.get_filestat().await?.into()) } else if table.is::>(fd) { - Ok(Ok(table - .get_dir(fd) - .map_err(convert)? - .get_filestat() - .await - .map_err(convert)? - .into())) + Ok(table.get_dir(fd)?.get_filestat().await?.into()) } else { Err(wasi::filesystem::ErrorCode::BadDescriptor.into()) } @@ -495,18 +427,16 @@ impl wasi::filesystem::Host for WasiCtx { fd: wasi::filesystem::Descriptor, at_flags: wasi::filesystem::PathFlags, path: String, - ) -> HostResult { + ) -> Result { let table = self.table(); - Ok(Ok(table - .get_dir(fd) - .map_err(convert)? + Ok(table + .get_dir(fd)? .get_path_filestat( &path, at_flags.contains(wasi::filesystem::PathFlags::SYMLINK_FOLLOW), ) - .await - .map(wasi::filesystem::DescriptorStat::from) - .map_err(convert)?)) + .await? + .into()) } async fn set_times_at( @@ -516,19 +446,17 @@ impl wasi::filesystem::Host for WasiCtx { path: String, atim: wasi::filesystem::NewTimestamp, mtim: wasi::filesystem::NewTimestamp, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { let table = self.table(); - Ok(Ok(table - .get_dir(fd) - .map_err(convert)? + Ok(table + .get_dir(fd)? .set_times( &path, system_time_spec_from_timestamp(atim), system_time_spec_from_timestamp(mtim), at_flags.contains(wasi::filesystem::PathFlags::SYMLINK_FOLLOW), ) - .await - .map_err(convert)?)) + .await?) } async fn link_at( @@ -539,18 +467,17 @@ impl wasi::filesystem::Host for WasiCtx { old_path: String, new_descriptor: wasi::filesystem::Descriptor, new_path: String, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { let table = self.table(); - let old_dir = table.get_dir(fd).map_err(convert)?; - let new_dir = table.get_dir(new_descriptor).map_err(convert)?; + let old_dir = table.get_dir(fd)?; + let new_dir = table.get_dir(new_descriptor)?; if old_at_flags.contains(wasi::filesystem::PathFlags::SYMLINK_FOLLOW) { - return Ok(Err(wasi::filesystem::ErrorCode::Invalid)); + return Err(wasi::filesystem::ErrorCode::Invalid.into()); } old_dir .hard_link(&old_path, new_dir.deref(), &new_path) - .await - .map_err(convert)?; - Ok(Ok(())) + .await?; + Ok(()) } async fn open_at( @@ -562,9 +489,9 @@ impl wasi::filesystem::Host for WasiCtx { flags: wasi::filesystem::DescriptorFlags, // TODO: How should this be used? _mode: wasi::filesystem::Modes, - ) -> HostResult { + ) -> Result { let table = self.table_mut(); - let dir = table.get_dir(fd).map_err(convert)?; + let dir = table.get_dir(fd)?; let symlink_follow = at_flags.contains(wasi::filesystem::PathFlags::SYMLINK_FOLLOW); @@ -575,12 +502,9 @@ impl wasi::filesystem::Host for WasiCtx { { return Err(wasi::filesystem::ErrorCode::Invalid.into()); } - let child_dir = dir - .open_dir(symlink_follow, &old_path) - .await - .map_err(convert)?; + let child_dir = dir.open_dir(symlink_follow, &old_path).await?; drop(dir); - Ok(Ok(table.push(Box::new(child_dir)).map_err(convert)?)) + Ok(table.push(Box::new(child_dir))?) } else { let file = dir .open_file( @@ -591,10 +515,9 @@ impl wasi::filesystem::Host for WasiCtx { flags.contains(wasi::filesystem::DescriptorFlags::WRITE), flags.into(), ) - .await - .map_err(convert)?; + .await?; drop(dir); - Ok(Ok(table.push(Box::new(file)).map_err(convert)?)) + Ok(table.push(Box::new(file))?) } } @@ -603,6 +526,7 @@ impl wasi::filesystem::Host for WasiCtx { if !(table.delete::>(fd).is_ok() || table.delete::>(fd).is_ok()) { + // this will trap: anyhow::bail!("{fd} is neither a file nor a directory"); } Ok(()) @@ -612,28 +536,23 @@ impl wasi::filesystem::Host for WasiCtx { &mut self, fd: wasi::filesystem::Descriptor, path: String, - ) -> HostResult { + ) -> Result { let table = self.table(); - let dir = table.get_dir(fd).map_err(convert)?; - let link = dir.read_link(&path).await.map_err(convert)?; + let dir = table.get_dir(fd)?; + let link = dir.read_link(&path).await?; Ok(link .into_os_string() .into_string() - .map_err(|_| wasi::filesystem::ErrorCode::IllegalByteSequence)) + .map_err(|_| wasi::filesystem::ErrorCode::IllegalByteSequence)?) } async fn remove_directory_at( &mut self, fd: wasi::filesystem::Descriptor, path: String, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { let table = self.table(); - Ok(Ok(table - .get_dir(fd) - .map_err(convert)? - .remove_dir(&path) - .await - .map_err(convert)?)) + Ok(table.get_dir(fd)?.remove_dir(&path).await?) } async fn rename_at( @@ -642,15 +561,14 @@ impl wasi::filesystem::Host for WasiCtx { old_path: String, new_fd: wasi::filesystem::Descriptor, new_path: String, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { let table = self.table(); - let old_dir = table.get_dir(fd).map_err(convert)?; - let new_dir = table.get_dir(new_fd).map_err(convert)?; + let old_dir = table.get_dir(fd)?; + let new_dir = table.get_dir(new_fd)?; old_dir .rename(&old_path, new_dir.deref(), &new_path) - .await - .map_err(convert)?; - Ok(Ok(())) + .await?; + Ok(()) } async fn symlink_at( @@ -658,28 +576,18 @@ impl wasi::filesystem::Host for WasiCtx { fd: wasi::filesystem::Descriptor, old_path: String, new_path: String, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { let table = self.table(); - Ok(Ok(table - .get_dir(fd) - .map_err(convert)? - .symlink(&old_path, &new_path) - .await - .map_err(convert)?)) + Ok(table.get_dir(fd)?.symlink(&old_path, &new_path).await?) } async fn unlink_file_at( &mut self, fd: wasi::filesystem::Descriptor, path: String, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { let table = self.table(); - Ok(Ok(table - .get_dir(fd) - .map_err(convert)? - .unlink_file(&path) - .await - .map_err(convert)?)) + Ok(table.get_dir(fd)?.unlink_file(&path).await?) } async fn change_file_permissions_at( @@ -688,7 +596,7 @@ impl wasi::filesystem::Host for WasiCtx { at_flags: wasi::filesystem::PathFlags, path: String, mode: wasi::filesystem::Modes, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { todo!() } @@ -698,42 +606,42 @@ impl wasi::filesystem::Host for WasiCtx { at_flags: wasi::filesystem::PathFlags, path: String, mode: wasi::filesystem::Modes, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { todo!() } async fn lock_shared( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { todo!() } async fn lock_exclusive( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { todo!() } async fn try_lock_shared( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { todo!() } async fn try_lock_exclusive( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { todo!() } async fn unlock( &mut self, fd: wasi::filesystem::Descriptor, - ) -> HostResult<(), wasi::filesystem::ErrorCode> { + ) -> Result<(), wasi::filesystem::Error> { todo!() } @@ -742,7 +650,8 @@ impl wasi::filesystem::Host for WasiCtx { fd: wasi::filesystem::Descriptor, offset: wasi::filesystem::Filesize, ) -> anyhow::Result { - let f = self.table_mut().get_file_mut(fd).map_err(convert)?; + // Trap if fd lookup fails: + let f = self.table_mut().get_file_mut(fd)?; // Duplicate the file descriptor so that we get an indepenent lifetime. let clone = f.dup(); @@ -753,8 +662,8 @@ impl wasi::filesystem::Host for WasiCtx { // Box it up. let boxed: Box = Box::new(reader); - // Insert the stream view into the table. - let index = self.table_mut().push(Box::new(boxed)).map_err(convert)?; + // Insert the stream view into the table. Trap if the table is full. + let index = self.table_mut().push(Box::new(boxed))?; Ok(index) } @@ -764,7 +673,8 @@ impl wasi::filesystem::Host for WasiCtx { fd: wasi::filesystem::Descriptor, offset: wasi::filesystem::Filesize, ) -> anyhow::Result { - let f = self.table_mut().get_file_mut(fd).map_err(convert)?; + // Trap if fd lookup fails: + let f = self.table_mut().get_file_mut(fd)?; // Duplicate the file descriptor so that we get an indepenent lifetime. let clone = f.dup(); @@ -775,8 +685,8 @@ impl wasi::filesystem::Host for WasiCtx { // Box it up. let boxed: Box = Box::new(writer); - // Insert the stream view into the table. - let index = self.table_mut().push(Box::new(boxed)).map_err(convert)?; + // Insert the stream view into the table. Trap if the table is full. + let index = self.table_mut().push(Box::new(boxed))?; Ok(index) } @@ -785,7 +695,8 @@ impl wasi::filesystem::Host for WasiCtx { &mut self, fd: wasi::filesystem::Descriptor, ) -> anyhow::Result { - let f = self.table_mut().get_file_mut(fd).map_err(convert)?; + // Trap if fd lookup fails: + let f = self.table_mut().get_file_mut(fd)?; // Duplicate the file descriptor so that we get an indepenent lifetime. let clone = f.dup(); @@ -796,8 +707,8 @@ impl wasi::filesystem::Host for WasiCtx { // Box it up. let boxed: Box = Box::new(appender); - // Insert the stream view into the table. - let index = self.table_mut().push(Box::new(boxed)).map_err(convert)?; + // Insert the stream view into the table. Trap if the table is full. + let index = self.table_mut().push(Box::new(boxed))?; Ok(index) } diff --git a/host/tests/command.rs b/host/tests/command.rs index 0711eeeb..2d1858e0 100644 --- a/host/tests/command.rs +++ b/host/tests/command.rs @@ -507,7 +507,11 @@ async fn run_dangling_fd(store: Store, wasi: Command) -> Result<()> { } async fn run_dangling_symlink(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + if cfg!(windows) { + expect_fail(run_with_temp_dir(store, wasi).await) + } else { + run_with_temp_dir(store, wasi).await + } } async fn run_directory_seek(store: Store, wasi: Command) -> Result<()> { @@ -555,7 +559,11 @@ async fn run_file_unbuffered_write(store: Store, wasi: Command) -> Resu } async fn run_interesting_paths(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + if cfg!(windows) { + expect_fail(run_with_temp_dir(store, wasi).await) + } else { + run_with_temp_dir(store, wasi).await + } } async fn run_isatty(store: Store, wasi: Command) -> Result<()> { @@ -563,7 +571,7 @@ async fn run_isatty(store: Store, wasi: Command) -> Result<()> { } async fn run_nofollow_errors(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + run_with_temp_dir(store, wasi).await } async fn run_path_exists(store: Store, wasi: Command) -> Result<()> { @@ -575,11 +583,15 @@ async fn run_path_filestat(store: Store, wasi: Command) -> Result<()> { } async fn run_path_link(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + if cfg!(windows) { + expect_fail(run_with_temp_dir(store, wasi).await) + } else { + run_with_temp_dir(store, wasi).await + } } async fn run_path_open_create_existing(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + run_with_temp_dir(store, wasi).await } async fn run_path_open_dirfd_not_dir(store: Store, wasi: Command) -> Result<()> { @@ -587,7 +599,7 @@ async fn run_path_open_dirfd_not_dir(store: Store, wasi: Command) -> Re } async fn run_path_open_missing(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + run_with_temp_dir(store, wasi).await } async fn run_path_open_read_without_rights(store: Store, wasi: Command) -> Result<()> { @@ -595,7 +607,11 @@ async fn run_path_open_read_without_rights(store: Store, wasi: Command) } async fn run_path_rename(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + if cfg!(windows) { + expect_fail(run_with_temp_dir(store, wasi).await) + } else { + run_with_temp_dir(store, wasi).await + } } async fn run_path_rename_dir_trailing_slashes(store: Store, wasi: Command) -> Result<()> { @@ -607,7 +623,11 @@ async fn run_path_rename_file_trailing_slashes(store: Store, wasi: Comm } async fn run_path_symlink_trailing_slashes(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + if cfg!(windows) { + expect_fail(run_with_temp_dir(store, wasi).await) + } else { + run_with_temp_dir(store, wasi).await + } } async fn run_poll_oneoff_files(store: Store, wasi: Command) -> Result<()> { @@ -627,7 +647,7 @@ async fn run_remove_directory_trailing_slashes(store: Store, wasi: Comm } async fn run_remove_nonempty_directory(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + run_with_temp_dir(store, wasi).await } async fn run_renumber(store: Store, wasi: Command) -> Result<()> { @@ -651,7 +671,11 @@ async fn run_symlink_filestat(store: Store, wasi: Command) -> Result<() } async fn run_symlink_loop(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + if cfg!(windows) { + expect_fail(run_with_temp_dir(store, wasi).await) + } else { + run_with_temp_dir(store, wasi).await + } } async fn run_truncation_rights(store: Store, wasi: Command) -> Result<()> { @@ -659,7 +683,7 @@ async fn run_truncation_rights(store: Store, wasi: Command) -> Result<( } async fn run_unlink_file_trailing_slashes(store: Store, wasi: Command) -> Result<()> { - expect_fail(run_with_temp_dir(store, wasi).await) + run_with_temp_dir(store, wasi).await } async fn run_export_cabi_realloc(mut store: Store, wasi: Command) -> Result<()> {