wasmer_wasix/syscalls/wasi/
fd_advise.rs

1use super::*;
2use crate::syscalls::*;
3
4/// ### `fd_advise()`
5/// Advise the system about how a file will be used
6/// Inputs:
7/// - `Fd fd`
8///     The file descriptor the advice applies to
9/// - `Filesize offset`
10///     The offset from which the advice applies
11/// - `Filesize len`
12///     The length from the offset to which the advice applies
13/// - `__wasi_advice_t advice`
14///     The advice to give
15#[instrument(level = "trace", skip_all, fields(%fd, %offset, %len, ?advice), ret)]
16pub fn fd_advise(
17    mut ctx: FunctionEnvMut<'_, WasiEnv>,
18    fd: WasiFd,
19    offset: Filesize,
20    len: Filesize,
21    advice: Advice,
22) -> Result<Errno, WasiError> {
23    WasiEnv::do_pending_operations(&mut ctx)?;
24
25    wasi_try_ok!(fd_advise_internal(&mut ctx, fd, offset, len, advice));
26    let env = ctx.data();
27
28    #[cfg(feature = "journal")]
29    if env.enable_journal {
30        JournalEffector::save_fd_advise(&mut ctx, fd, offset, len, advice).map_err(|err| {
31            tracing::error!("failed to save file descriptor advise event - {}", err);
32            WasiError::Exit(ExitCode::from(Errno::Fault))
33        })?;
34    }
35
36    Ok(Errno::Success)
37}
38
39pub(crate) fn fd_advise_internal(
40    ctx: &mut FunctionEnvMut<'_, WasiEnv>,
41    fd: WasiFd,
42    offset: Filesize,
43    len: Filesize,
44    advice: Advice,
45) -> Result<(), Errno> {
46    // Instead of unconditionally returning OK.  This barebones implementation
47    // only performs basic fd and rights checks.
48
49    let env = ctx.data();
50    let (_, mut state) = unsafe { env.get_memory_and_wasi_state(&ctx, 0) };
51    let fd_entry = state.fs.get_fd(fd)?;
52    let inode = fd_entry.inode;
53
54    if !fd_entry.inner.rights.contains(Rights::FD_ADVISE) {
55        return Err(Errno::Access);
56    }
57
58    let _end = offset.checked_add(len).ok_or(Errno::Inval)?;
59
60    Ok(())
61}