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::p2::bindings::sync::filesystem::preopens::Host for VfsHostState {
9    fn get_directories(
10        &mut self,
11    ) -> Result<
12        Vec<(
13            Resource<wasmtime_wasi::p2::bindings::filesystem::types::Descriptor>,
14            String,
15        )>,
16        wasmtime::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| wasmtime::format_err!("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::<
49                        Resource<wasmtime_wasi::p2::bindings::filesystem::types::Descriptor>,
50                    >()
51            );
52            assert!(
53                align_of::<Resource<FsDescriptorWrapper>>()
54                    == align_of::<
55                        Resource<wasmtime_wasi::p2::bindings::filesystem::types::Descriptor>,
56                    >()
57            );
58        };
59        let host_descriptor = unsafe {
60            std::mem::transmute::<
61                Resource<FsDescriptorWrapper>,
62                Resource<wasmtime_wasi::p2::bindings::filesystem::types::Descriptor>,
63            >(wrapper_resource)
64        };
65
66        log::debug!("[VFS-HOST] Returning preopened root directory");
67        Ok(vec![(host_descriptor, "/".to_string())])
68    }
69}