wasmer_wasix/syscalls/wasi/
fd_renumber.rs1use super::*;
2use crate::syscalls::*;
3
4#[instrument(level = "trace", skip_all, fields(%from, %to), ret)]
12pub fn fd_renumber(
13 mut ctx: FunctionEnvMut<'_, WasiEnv>,
14 from: WasiFd,
15 to: WasiFd,
16) -> Result<Errno, WasiError> {
17 WasiEnv::do_pending_operations(&mut ctx)?;
18
19 let ret = fd_renumber_internal(&mut ctx, from, to)?;
20 let env = ctx.data();
21
22 if ret == Errno::Success {
23 #[cfg(feature = "journal")]
24 if env.enable_journal {
25 JournalEffector::save_fd_renumber(&mut ctx, from, to).map_err(|err| {
26 tracing::error!("failed to save file descriptor renumber event - {}", err);
27 WasiError::Exit(ExitCode::from(Errno::Fault))
28 })?;
29 }
30 }
31
32 Ok(ret)
33}
34
35pub(crate) fn fd_renumber_internal(
36 ctx: &mut FunctionEnvMut<'_, WasiEnv>,
37 from: WasiFd,
38 to: WasiFd,
39) -> Result<Errno, WasiError> {
40 if from == to {
41 return Ok(Errno::Success);
42 }
43 let env = ctx.data();
44 let (_, mut state) = unsafe { env.get_memory_and_wasi_state(&ctx, 0) };
45
46 if let Ok(fd) = state.fs.get_fd(to) {
47 if !fd.is_stdio && fd.inode.is_preopened {
48 warn!(
53 "FD ({to}) is a pre-open and should not be closed, \
54 but will be closed in response to an fd_renumber operation. \
55 This will likely break stuff."
56 );
57 }
58 match __asyncify_light(env, None, state.fs.flush(to))? {
59 Ok(_) | Err(Errno::Isdir) | Err(Errno::Io) | Err(Errno::Access) => {}
60 Err(e) => {
61 return Ok(e);
62 }
63 }
64 wasi_try_ok!(state.fs.close_fd(to));
65 }
66
67 let mut fd_map = state.fs.fd_map.write().unwrap();
68 let fd_entry = wasi_try_ok!(fd_map.get(from).ok_or(Errno::Badf));
69
70 let new_fd_entry = Fd {
71 inner: FdInner {
73 offset: fd_entry.inner.offset.clone(),
74 rights: fd_entry.inner.rights_inheriting,
75 fd_flags: {
76 let mut f = fd_entry.inner.fd_flags;
77 f.set(Fdflagsext::CLOEXEC, false);
78 f
79 },
80 ..fd_entry.inner
81 },
82 inode: fd_entry.inode.clone(),
83 ..*fd_entry
84 };
85
86 if !fd_map.insert(true, to, new_fd_entry) {
88 panic!("Internal error: expected FD {to} to be free after closing in fd_renumber");
89 }
90
91 Ok(Errno::Success)
92}