wasmer_wasix/syscalls/wasi/
fd_prestat_dir_name.rs

1use super::*;
2use crate::syscalls::*;
3
4#[instrument(level = "trace", skip_all, fields(%fd, path = field::Empty), ret)]
5pub fn fd_prestat_dir_name<M: MemorySize>(
6    ctx: FunctionEnvMut<'_, WasiEnv>,
7    fd: WasiFd,
8    path: WasmPtr<u8, M>,
9    path_len: M::Offset,
10) -> Errno {
11    let env = ctx.data();
12    let (memory, mut state) = unsafe { env.get_memory_and_wasi_state(&ctx, 0) };
13    let path_chars = wasi_try_mem!(path.slice(&memory, path_len));
14
15    let inode = wasi_try!(state.fs.get_fd_inode(fd));
16    let name = inode.name.read().unwrap();
17    Span::current().record("path", name.as_ref());
18
19    // check inode-val.is_preopened?
20
21    let guard = inode.read();
22    match guard.deref() {
23        Kind::Dir { .. } | Kind::Root { .. } => {
24            let path_len: u64 = path_len.into();
25            let name_len = name.len() as u64;
26            if name_len <= path_len {
27                wasi_try_mem!(
28                    path_chars
29                        .subslice(0..name_len)
30                        .write_slice(name.as_bytes())
31                );
32                // Note: We don't write a null terminator since WASI spec doesn't require it
33                // and pr_name_len already gives the exact length
34
35                Errno::Success
36            } else {
37                Errno::Overflow
38            }
39        }
40        Kind::Symlink { .. }
41        | Kind::Buffer { .. }
42        | Kind::File { .. }
43        | Kind::Socket { .. }
44        | Kind::PipeRx { .. }
45        | Kind::PipeTx { .. }
46        | Kind::DuplexPipe { .. }
47        | Kind::EventNotifications { .. }
48        | Kind::Epoll { .. } => Errno::Notdir,
49    }
50}