wasmer_wasix/syscalls/wasi/
fd_filestat_get.rs

1use super::*;
2use crate::syscalls::*;
3use crate::types::wasi::Snapshot0Filestat;
4
5/// ### `fd_filestat_get()`
6/// Get the metadata of an open file
7///
8/// Input:
9/// - `Fd fd`
10///   The open file descriptor whose metadata will be read
11///
12/// Output:
13/// - `Filestat *buf`
14///   Where the metadata from `fd` will be written
15#[instrument(level = "trace", skip_all, fields(%fd, size = field::Empty, mtime = field::Empty), ret)]
16pub fn fd_filestat_get<M: MemorySize>(
17    mut ctx: FunctionEnvMut<'_, WasiEnv>,
18    fd: WasiFd,
19    buf: WasmPtr<Filestat, M>,
20) -> Result<Errno, WasiError> {
21    WasiEnv::do_pending_operations(&mut ctx)?;
22
23    let stat = wasi_try_ok!(fd_filestat_get_internal(&mut ctx, fd));
24
25    // These two values have proved to be helpful in multiple investigations
26    Span::current().record("size", stat.st_size);
27    Span::current().record("mtime", stat.st_mtim);
28
29    let env = ctx.data();
30    let (memory, _) = unsafe { env.get_memory_and_wasi_state(&ctx, 0) };
31    let buf = buf.deref(&memory);
32    wasi_try_mem_ok!(buf.write(stat));
33
34    Ok(Errno::Success)
35}
36
37/// ### `fd_filestat_get()`
38/// Get the metadata of an open file
39///
40/// Input:
41/// - `__wasi_fd_t fd`
42///   The open file descriptor whose metadata will be read
43///
44/// Output:
45/// - `__wasi_filestat_t *buf`
46///   Where the metadata from `fd` will be written
47pub(crate) fn fd_filestat_get_internal(
48    ctx: &mut FunctionEnvMut<'_, WasiEnv>,
49    fd: WasiFd,
50) -> Result<Filestat, Errno> {
51    let env = ctx.data();
52    let (_, state, inodes) = unsafe { env.get_memory_and_wasi_state_and_inodes(&ctx, 0) };
53    let fd_entry = state.fs.get_fd(fd)?;
54    if !fd_entry.inner.rights.contains(Rights::FD_FILESTAT_GET) {
55        return Err(Errno::Access);
56    }
57
58    state.fs.filestat_fd(fd)
59}
60
61/// ### `fd_filestat_get_old()`
62/// Get the metadata of an open file
63///
64/// Input:
65/// - `Fd fd`
66///   The open file descriptor whose metadata will be read
67///
68/// Output:
69/// - `Snapshot0Filestat *buf`
70///   Where the metadata from `fd` will be written
71#[instrument(level = "trace", skip_all, fields(%fd), ret)]
72pub fn fd_filestat_get_old<M: MemorySize>(
73    mut ctx: FunctionEnvMut<'_, WasiEnv>,
74    fd: WasiFd,
75    buf: WasmPtr<Snapshot0Filestat, M>,
76) -> Errno {
77    let stat = wasi_try!(fd_filestat_get_internal(&mut ctx, fd));
78
79    let env = ctx.data();
80    let (memory, _) = unsafe { env.get_memory_and_wasi_state(&ctx, 0) };
81    let old_stat = Snapshot0Filestat {
82        st_dev: stat.st_dev,
83        st_ino: stat.st_ino,
84        st_filetype: stat.st_filetype,
85        st_nlink: stat.st_nlink as u32,
86        st_size: stat.st_size,
87        st_atim: stat.st_atim,
88        st_mtim: stat.st_mtim,
89        st_ctim: stat.st_ctim,
90    };
91
92    let buf = buf.deref(&memory);
93    wasi_try_mem!(buf.write(old_stat));
94
95    Errno::Success
96}