Skip to main content

vfs_host/
filesystem_preopens.rs

1// WASI Filesystem Preopens Host Implementation
2//
3// Implements wasi:filesystem/preopens interface using fs-core directly
4
5use super::{FsDescriptorWrapper, VfsHostState};
6use wasmtime::component::Resource;
7
8impl wasmtime_wasi::bindings::sync::filesystem::preopens::Host for VfsHostState {
9    fn get_directories(
10        &mut self,
11    ) -> Result<
12        Vec<(
13            Resource<wasmtime_wasi::bindings::filesystem::types::Descriptor>,
14            String,
15        )>,
16        anyhow::Error,
17    > {
18        log::debug!("[VFS-HOST] get_directories() called");
19
20        // Open root directory using fs-core directly (no external lock needed)
21        // O_RDONLY | O_DIRECTORY flags
22        const O_RDONLY: u32 = 0;
23        const O_DIRECTORY: u32 = 0x10000;
24
25        let fd = self
26            .shared_vfs
27            .open_path_with_flags("/", O_RDONLY | O_DIRECTORY)
28            .map_err(|e| anyhow::anyhow!("Failed to open root directory: {:?}", e))?;
29
30        log::debug!("[VFS-HOST] Opened root directory with fd={}", fd);
31
32        // Create wrapper with directory path for relative path resolution
33        let wrapper = FsDescriptorWrapper {
34            fd,
35            path: Some("/".to_string()),
36        };
37
38        // Push to ResourceTable
39        let wrapper_resource: Resource<FsDescriptorWrapper> = self.table.push(wrapper)?;
40
41        // Transmute Resource<FsDescriptorWrapper> to Resource<Descriptor>
42        // SAFETY: Resource<T> is a transparent u32 wrapper, so transmute is safe
43        // Compile-time checks ensure size and alignment match
44        const _: () = {
45            use std::mem::{align_of, size_of};
46            assert!(
47                size_of::<Resource<FsDescriptorWrapper>>()
48                    == size_of::<Resource<wasmtime_wasi::bindings::filesystem::types::Descriptor>>(
49                    )
50            );
51            assert!(
52                align_of::<Resource<FsDescriptorWrapper>>()
53                    == align_of::<Resource<wasmtime_wasi::bindings::filesystem::types::Descriptor>>(
54                    )
55            );
56        };
57        let host_descriptor = unsafe {
58            std::mem::transmute::<
59                Resource<FsDescriptorWrapper>,
60                Resource<wasmtime_wasi::bindings::filesystem::types::Descriptor>,
61            >(wrapper_resource)
62        };
63
64        log::debug!("[VFS-HOST] Returning preopened root directory");
65        Ok(vec![(host_descriptor, "/".to_string())])
66    }
67}