#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
use core::any::Any;
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
use core::borrow::Borrow;
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
use core::ops::Deref;
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
use smallstr::SmallString;
#[cfg(feature = "alloc")]
use crate::memory::WasmAccessDynCompatible as _;
use crate::memory::{WasmAccess, WasmAccessDynCompatibleRaw, WasmAccessName};
#[cfg(feature = "dynamic-fs")]
pub mod dynamic;
#[cfg(feature = "embedded-fs")]
pub mod embedded;
#[cfg(feature = "multiple-fs")]
pub mod multiple;
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
pub mod stdio;
#[cfg(any(
feature = "embedded-fs",
feature = "dynamic-fs",
feature = "multiple-fs"
))]
pub(crate) mod trace;
pub(crate) mod types;
use crate::__private::wasip1;
pub use self::types::{BoxedInode, InodeIdCommon, OpenFdInfo, OpenFdInfoWithInode};
use crate::__private::wasip1::*;
pub struct FilestatWithoutDevice {
pub ino: Inode,
pub filetype: Filetype,
pub nlink: Linkcount,
pub size: Filesize,
pub atim: Timestamp,
pub mtim: Timestamp,
pub ctim: Timestamp,
}
pub use const_struct::ConstDefault;
pub trait WasiAddInfo: core::fmt::Debug + Clone + Copy {
fn access_time(&self) -> Timestamp {
0
}
fn set_access_time(&mut self, _atime: Timestamp) {}
fn modification_time(&self) -> Timestamp {
0
}
fn set_modification_time(&mut self, _mtime: Timestamp) {}
fn creation_time(&self) -> Timestamp {
0
}
fn set_creation_time(&mut self, _ctime: Timestamp) {}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct NoAddInfo;
impl WasiAddInfo for NoAddInfo {}
impl ConstDefault for NoAddInfo {
const DEFAULT: Self = Self;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct DefaultAddInfo {
pub atim: Timestamp,
pub mtim: Timestamp,
pub ctim: Timestamp,
}
impl ConstDefault for DefaultAddInfo {
const DEFAULT: Self = Self {
atim: 0,
mtim: 0,
ctim: 0,
};
}
impl WasiAddInfo for DefaultAddInfo {
fn access_time(&self) -> Timestamp {
self.atim
}
fn set_access_time(&mut self, atime: Timestamp) {
self.atim = atime;
}
fn modification_time(&self) -> Timestamp {
self.mtim
}
fn set_modification_time(&mut self, mtime: Timestamp) {
self.mtim = mtime;
}
fn creation_time(&self) -> Timestamp {
self.ctim
}
fn set_creation_time(&mut self, ctime: Timestamp) {
self.ctim = ctime;
}
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
#[allow(dead_code)]
pub(crate) trait Wasip1LFSBaseWrapper: Wasip1LFSBase {
fn downcast_inode(inode: &dyn InodeIdCommon) -> &<Self as Wasip1LFSBase>::Inode;
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
impl<T: Wasip1LFSBase + ?Sized> Wasip1LFSBaseWrapper for T
where
<Self as Wasip1LFSBase>::Inode: 'static,
{
fn downcast_inode(base_inode: &dyn InodeIdCommon) -> &<Self as Wasip1LFSBase>::Inode {
let inode = base_inode as &dyn Any;
#[cfg(feature = "trace")]
{
inode
.downcast_ref::<<Self as Wasip1LFSBase>::Inode>()
.unwrap_or_else(|| {
panic!(
"Failed to downcast inode. Expected type: {}, but got a different type. {:?}",
core::any::type_name::<<Self as Wasip1LFSBase>::Inode>(),
base_inode
)
})
}
#[cfg(not(feature = "trace"))]
{
inode
.downcast_ref::<<Self as Wasip1LFSBase>::Inode>()
.unwrap()
}
}
}
pub trait Wasip1LFSBase: core::fmt::Debug {
type Inode: InodeIdCommon;
fn fd_write_raw<Wasm: WasmAccess>(
&self,
inode: &Self::Inode,
data: *const u8,
data_len: usize,
) -> Result<Size, wasip1::Errno>;
fn fd_write_stdout_raw<Wasm: WasmAccess>(
&self,
data: *const u8,
data_len: usize,
) -> Result<Size, wasip1::Errno>;
fn fd_write_stderr_raw<Wasm: WasmAccess>(
&self,
data: *const u8,
data_len: usize,
) -> Result<Size, wasip1::Errno>;
fn is_dir(&self, inode: &Self::Inode) -> bool;
fn fd_readdir_raw<Wasm: WasmAccess>(
&self,
inode: &Self::Inode,
buf: *mut u8,
buf_len: usize,
cookie: Dircookie,
) -> Result<(Size, Dircookie), wasip1::Errno>;
fn path_filestat_get_raw<Wasm: WasmAccess>(
&self,
inode: &Self::Inode,
flags: wasip1::Lookupflags,
path_ptr: *const u8,
path_len: usize,
) -> Result<FilestatWithoutDevice, wasip1::Errno>;
fn fd_prestat_get_raw<Wasm: WasmAccess>(
&self,
inode: &Self::Inode,
) -> Result<wasip1::Prestat, wasip1::Errno>;
fn fd_prestat_dir_name_raw<Wasm: WasmAccess>(
&self,
inode: &Self::Inode,
dir_path_ptr: *mut u8,
dir_path_len: usize,
) -> Result<(), wasip1::Errno>;
fn fd_filestat_get_raw<Wasm: WasmAccess>(
&self,
inode: &Self::Inode,
) -> Result<FilestatWithoutDevice, wasip1::Errno>;
fn fd_pread_raw<Wasm: WasmAccess>(
&self,
inode: &Self::Inode,
buf: *mut u8,
buf_len: usize,
offset: usize,
) -> Result<Size, wasip1::Errno>;
fn fd_read_stdin_raw<Wasm: WasmAccess>(
&self,
buf: *mut u8,
buf_len: usize,
) -> Result<Size, wasip1::Errno>;
fn path_open_raw<Wasm: WasmAccess>(
&self,
dir_ino: &Self::Inode,
dir_flags: wasip1::Fdflags,
path_ptr: *const u8,
path_len: usize,
o_flags: wasip1::Oflags,
fs_rights_base: wasip1::Rights,
fs_rights_inheriting: wasip1::Rights,
fd_flags: wasip1::Fdflags,
) -> Result<Self::Inode, wasip1::Errno>;
fn path_readlink_raw<Wasm: WasmAccess>(
&self,
inode: &Self::Inode,
path_ptr: *const u8,
path_len: usize,
buf: *mut u8,
buf_len: usize,
) -> Result<Size, wasip1::Errno>;
}
#[cfg(feature = "embedded-fs")]
pub trait EmbeddedLFS: Wasip1LFSBase
where
Self::Inode: 'static,
{
const PRE_OPEN: &'static [Self::Inode];
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
#[allow(dead_code)]
pub trait DynamicLFS: Wasip1LFSBase {
fn pre_open_inodes(&self) -> impl IntoIterator<Item = (Self::Inode, impl DerefToStrCustom)>;
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
#[allow(dead_code)]
pub trait DerefToStrCustom {
fn deref_to_str<'a>(&'a self) -> &'a str;
}
#[cfg(all(
any(feature = "embedded-fs", feature = "dynamic-fs"),
feature = "alloc",
not(feature = "std")
))]
impl DerefToStrCustom for alloc::string::String {
fn deref_to_str<'a>(&'a self) -> &'a str {
self.as_str()
}
}
#[cfg(all(
any(feature = "embedded-fs", feature = "dynamic-fs"),
feature = "alloc",
not(feature = "std")
))]
impl DerefToStrCustom for &alloc::string::String {
fn deref_to_str<'a>(&'a self) -> &'a str {
self.as_str()
}
}
#[cfg(all(any(feature = "embedded-fs", feature = "dynamic-fs"), feature = "std"))]
impl DerefToStrCustom for std::string::String {
fn deref_to_str<'a>(&'a self) -> &'a str {
self.as_str()
}
}
#[cfg(all(any(feature = "embedded-fs", feature = "dynamic-fs"), feature = "std"))]
impl DerefToStrCustom for &std::string::String {
fn deref_to_str<'a>(&'a self) -> &'a str {
self.as_str()
}
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
impl DerefToStrCustom for str {
fn deref_to_str<'a>(&'a self) -> &'a str {
self
}
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
impl DerefToStrCustom for &str {
fn deref_to_str<'a>(&'a self) -> &'a str {
self
}
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
impl<const N: usize> DerefToStrCustom for SmallString<[u8; N]> {
fn deref_to_str<'a>(&'a self) -> &'a str {
self.as_str()
}
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
impl<const N: usize> DerefToStrCustom for &SmallString<[u8; N]> {
fn deref_to_str<'a>(&'a self) -> &'a str {
self.as_str()
}
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
impl<T> DerefToStrCustom for (T,)
where
T: Deref,
T::Target: Borrow<str>,
{
fn deref_to_str<'a>(&'a self) -> &'a str {
self.0.deref().borrow()
}
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
impl<T, U> DerefToStrCustom for (T, U)
where
T: Deref,
T::Target: Borrow<str>,
{
fn deref_to_str<'a>(&'a self) -> &'a str {
self.0.deref().borrow()
}
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
#[allow(dead_code)]
pub trait Wasip1DynCompatibleLFSSlice: core::fmt::Debug {
fn index(
&self,
index: usize,
f: &mut dyn for<'a, 'b> FnMut(Option<(&'a dyn InodeIdCommon, &'b dyn DerefToStrCustom)>),
);
}
#[cfg(any(feature = "embedded-fs", feature = "dynamic-fs"))]
#[allow(dead_code)]
pub trait Wasip1DynCompatibleLFS<B: BoxedInode>: core::fmt::Debug {
fn pre_open_inodes(&self, f: &mut dyn for<'a> FnMut(&'a dyn Wasip1DynCompatibleLFSSlice));
fn fd_write_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
inode: &dyn InodeIdCommon,
data: *const u8,
data_len: usize,
) -> Result<Size, wasip1::Errno>;
fn fd_write_stdout_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
data: *const u8,
data_len: usize,
) -> Result<Size, wasip1::Errno>;
fn fd_write_stderr_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
data: *const u8,
data_len: usize,
) -> Result<Size, wasip1::Errno>;
fn fd_readdir_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
inode: &dyn InodeIdCommon,
buf: *mut u8,
buf_len: usize,
cookie: Dircookie,
) -> Result<(Size, Dircookie), wasip1::Errno>;
fn path_filestat_get_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
inode: &dyn InodeIdCommon,
flags: wasip1::Lookupflags,
path_ptr: *const u8,
path_len: usize,
) -> Result<FilestatWithoutDevice, wasip1::Errno>;
fn fd_prestat_get_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
inode: &dyn InodeIdCommon,
) -> Result<wasip1::Prestat, wasip1::Errno>;
fn fd_prestat_dir_name_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
inode: &dyn InodeIdCommon,
dir_path_ptr: *mut u8,
dir_path_len: usize,
) -> Result<(), wasip1::Errno>;
fn fd_filestat_get_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
inode: &dyn InodeIdCommon,
) -> Result<FilestatWithoutDevice, wasip1::Errno>;
fn fd_pread_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
inode: &dyn InodeIdCommon,
buf: *mut u8,
buf_len: usize,
offset: usize,
) -> Result<Size, wasip1::Errno>;
fn fd_read_stdin_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
buf: *mut u8,
buf_len: usize,
) -> Result<Size, wasip1::Errno>;
fn path_open_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
dir_ino: &dyn InodeIdCommon,
dir_flags: wasip1::Fdflags,
path_ptr: *const u8,
path_len: usize,
o_flags: wasip1::Oflags,
fs_rights_base: wasip1::Rights,
fs_rights_inheriting: wasip1::Rights,
fd_flags: wasip1::Fdflags,
) -> Result<B, wasip1::Errno>;
fn path_readlink_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
inode: &dyn InodeIdCommon,
path_ptr: *const u8,
path_len: usize,
buf: *mut u8,
buf_len: usize,
) -> Result<Size, wasip1::Errno>;
}
pub trait Wasip1FileTrait: core::fmt::Debug {
fn size(&self) -> usize;
#[allow(unused_variables)]
fn pread(&self, buf: &mut [u8], offset: usize) -> Result<usize, wasip1::Errno> {
return Err(wasip1::ERRNO_NOSYS);
}
#[allow(unused_variables)]
fn pread_raw<Wasm: WasmAccess>(
&self,
buf_ptr: *mut u8,
buf_len: usize,
offset: usize,
) -> Result<usize, wasip1::Errno> {
#[cfg(feature = "alloc")]
{
use crate::utils::alloc_buff;
let (_, nread) = unsafe {
alloc_buff(buf_len, |b| {
let nread = self.pread(b, offset)?;
Wasm::memcpy(buf_ptr, &b[..nread]);
Ok(nread)
})
};
nread
}
#[cfg(not(feature = "alloc"))]
{
Err(wasip1::ERRNO_NOSYS)
}
}
#[allow(unused_variables)]
fn pread_raw_dyn_compatible(
&self,
access: &dyn WasmAccessDynCompatibleRaw,
buf_ptr: *mut u8,
buf_len: usize,
offset: usize,
) -> Result<usize, wasip1::Errno> {
#[cfg(feature = "alloc")]
{
use crate::utils::alloc_buff;
let (_, nread) = unsafe {
alloc_buff(buf_len, |b| {
let nread = self.pread(b, offset)?;
access.memcpy_with(buf_ptr, &b[..nread]);
Ok(nread)
})
};
nread
}
#[cfg(not(feature = "alloc"))]
{
Err(wasip1::ERRNO_NOSYS)
}
}
}
pub trait Wasip1FileSystem: core::fmt::Debug {
fn fd_write_raw<Wasm: WasmAccess + WasmAccessName>(
&self,
fd: Fd,
iovs_ptr: *const Ciovec,
iovs_len: usize,
nwritten: *mut Size,
) -> wasip1::Errno;
fn fd_readdir_raw<Wasm: WasmAccess + WasmAccessName>(
&self,
fd: Fd,
buf: *mut u8,
buf_len: usize,
cookie: Dircookie,
nread: *mut Size,
) -> wasip1::Errno;
fn path_filestat_get_raw<Wasm: WasmAccess + WasmAccessName>(
&self,
fd: Fd,
flags: wasip1::Lookupflags,
path_ptr: *const u8,
path_len: usize,
filestat: *mut wasip1::Filestat,
) -> wasip1::Errno;
fn fd_prestat_get_raw<Wasm: WasmAccess + WasmAccessName>(
&self,
fd: Fd,
prestat: *mut wasip1::Prestat,
) -> wasip1::Errno;
fn fd_prestat_dir_name_raw<Wasm: WasmAccess + WasmAccessName>(
&self,
fd: Fd,
dir_path_ptr: *mut u8,
dir_path_len: usize,
) -> wasip1::Errno;
fn fd_close_raw<Wasm: WasmAccess + WasmAccessName>(&self, fd: Fd) -> wasip1::Errno;
fn fd_filestat_get_raw<Wasm: WasmAccess + WasmAccessName>(
&self,
fd: Fd,
filestat: *mut wasip1::Filestat,
) -> wasip1::Errno;
fn fd_fdstat_get_raw<Wasm: WasmAccess + WasmAccessName>(
&self,
fd: Fd,
fdstat: *mut wasip1::Fdstat,
) -> wasip1::Errno;
fn fd_read_raw<Wasm: WasmAccess + WasmAccessName>(
&self,
fd: Fd,
iovs_ptr: *const Ciovec,
iovs_len: usize,
nread: *mut Size,
) -> wasip1::Errno;
fn path_open_raw<Wasm: WasmAccess + WasmAccessName>(
&self,
dir_fd: Fd,
dir_flags: wasip1::Fdflags,
path_ptr: *const u8,
path_len: usize,
o_flags: wasip1::Oflags,
fs_rights_base: wasip1::Rights,
fs_rights_inheriting: wasip1::Rights,
fd_flags: wasip1::Fdflags,
fd_ret: *mut wasip1::Fd,
) -> wasip1::Errno;
fn path_readlink_raw<Wasm: WasmAccess + WasmAccessName>(
&self,
fd: Fd,
path_ptr: *const u8,
path_len: usize,
buf: *mut u8,
buf_len: usize,
buf_nread: *mut Size,
) -> wasip1::Errno;
}
#[macro_export]
macro_rules! plug_fs {
($state:expr, $($wasm:ident),* $(,)?) => {
$crate::__as_t!(@through, $($wasm),* => $crate::plug_fs, @inner, $state);
const _: () = {
let _ = || { $state };
};
};
(@inner, $state:expr, $($wasm:ident),* $(,)?) => {
$crate::__private::paste::paste! {
$(
#[cfg(target_os = "wasi")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _fd_write>](
fd: $crate::__private::wasip1::Fd,
iovs_ptr: *const $crate::__private::wasip1::Ciovec,
iovs_len: usize,
nwritten: *mut usize,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::fd_write_raw::<T>(state, fd, iovs_ptr, iovs_len, nwritten)
}
#[cfg(target_os = "wasi")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _fd_readdir>](
fd: $crate::__private::wasip1::Fd,
buf: *mut u8,
buf_len: usize,
cookie: $crate::__private::wasip1::Dircookie,
nread: *mut $crate::__private::wasip1::Size,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::fd_readdir_raw::<T>(state, fd, buf, buf_len, cookie, nread)
}
#[cfg(target_os = "wasi")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _path_filestat_get>](
fd: $crate::__private::wasip1::Fd,
flags: $crate::__private::wasip1::Lookupflags,
path_ptr: *const u8,
path_len: usize,
filestat: *mut $crate::__private::wasip1::Filestat,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::path_filestat_get_raw::<T>(state, fd, flags, path_ptr, path_len, filestat)
}
#[cfg(target_os = "wasi")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _fd_prestat_get>](
fd: $crate::__private::wasip1::Fd,
prestat: *mut $crate::__private::wasip1::Prestat,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::fd_prestat_get_raw::<T>(state, fd, prestat)
}
#[cfg(target_os = "wasi")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _fd_prestat_dir_name>](
fd: $crate::__private::wasip1::Fd,
dir_path_ptr: *mut u8,
dir_path_len: usize,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::fd_prestat_dir_name_raw::<T>(state, fd, dir_path_ptr, dir_path_len)
}
#[cfg(target_os = "wasi")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _fd_close>](
fd: $crate::__private::wasip1::Fd,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::fd_close_raw::<T>(state, fd)
}
#[unsafe(no_mangle)]
#[cfg(target_os = "wasi")]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _path_open>](
fd: $crate::__private::wasip1::Fd,
dir_flags: $crate::__private::wasip1::Fdflags,
path_ptr: *const u8,
path_len: usize,
o_flags: $crate::__private::wasip1::Oflags,
fs_rights_base: $crate::__private::wasip1::Rights,
fs_rights_inheriting: $crate::__private::wasip1::Rights,
fd_flags: $crate::__private::wasip1::Fdflags,
fd_ret: *mut $crate::__private::wasip1::Fd,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::path_open_raw::<T>(state, fd, dir_flags, path_ptr, path_len, o_flags, fs_rights_base, fs_rights_inheriting, fd_flags, fd_ret)
}
#[unsafe(no_mangle)]
#[cfg(target_os = "wasi")]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _fd_read>](
fd: $crate::__private::wasip1::Fd,
iovs_ptr: *const $crate::__private::wasip1::Ciovec,
iovs_len: usize,
nread_ret: *mut $crate::__private::wasip1::Size,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::fd_read_raw::<T>(state, fd, iovs_ptr, iovs_len, nread_ret)
}
#[unsafe(no_mangle)]
#[cfg(target_os = "wasi")]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _fd_filestat_get>](
fd: $crate::__private::wasip1::Fd,
filestat: *mut $crate::__private::wasip1::Filestat,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::fd_filestat_get_raw::<T>(state, fd, filestat)
}
#[unsafe(no_mangle)]
#[cfg(target_os = "wasi")]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _fd_fdstat_get>](
fd: $crate::__private::wasip1::Fd,
fdstat: *mut $crate::__private::wasip1::Fdstat,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::fd_fdstat_get_raw::<T>(state, fd, fdstat)
}
#[unsafe(no_mangle)]
#[cfg(target_os = "wasi")]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _path_readlink>](
fd: $crate::__private::wasip1::Fd,
path_ptr: *const u8,
path_len: usize,
buf: *mut u8,
buf_len: usize,
buf_nread: *mut $crate::__private::wasip1::Size,
) -> $crate::__private::wasip1::Errno {
let state = $state;
$crate::__as_t!(@as_t, $wasm);
$crate::file::Wasip1FileSystem::path_readlink_raw::<T>(state, fd, path_ptr, path_len, buf, buf_len, buf_nread)
}
)*
}
};
}