diff --git a/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs b/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs index 50d62a3f8b27..1e23b681eac0 100644 --- a/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs +++ b/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs @@ -289,8 +289,28 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { unimplemented!("fd_readdir") } - fn fd_renumber(&self, _fd: types::Fd, _to: types::Fd) -> Result<()> { - unimplemented!("fd_renumber") + fn fd_renumber(&self, from: types::Fd, to: types::Fd) -> Result<()> { + trace!("fd_renumber(from={:?}, to={:?})", from, to); + + if unsafe { !self.contains_entry(from) } { + return Err(Errno::Badf); + } + + // Don't allow renumbering over a pre-opened resource. + // TODO: Eventually, we do want to permit this, once libpreopen in + // userspace is capable of removing entries from its tables as well. + let from_fe = unsafe { self.get_entry(from)? }; + if from_fe.preopen_path.is_some() { + return Err(Errno::Notsup); + } + if let Ok(to_fe) = unsafe { self.get_entry(to) } { + if to_fe.preopen_path.is_some() { + return Err(Errno::Notsup); + } + } + let fe = self.remove_entry(from)?; + self.insert_entry_at(to, fe); + Ok(()) } fn fd_seek(