Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wasi/src/p3/filesystem/mod.rs
1692 views
1
mod host;
2
3
use crate::TrappableError;
4
use crate::filesystem::{WasiFilesystem, WasiFilesystemView};
5
use crate::p3::bindings::filesystem::{preopens, types};
6
use wasmtime::component::Linker;
7
8
pub type FilesystemResult<T> = Result<T, FilesystemError>;
9
pub type FilesystemError = TrappableError<types::ErrorCode>;
10
11
/// Add all WASI interfaces from this module into the `linker` provided.
12
///
13
/// This function will add all interfaces implemented by this module to the
14
/// [`Linker`], which corresponds to the `wasi:filesystem/imports` world supported by
15
/// this module.
16
///
17
/// This is low-level API for advanced use cases,
18
/// [`wasmtime_wasi::p3::add_to_linker`](crate::p3::add_to_linker) can be used instead
19
/// to add *all* wasip3 interfaces (including the ones from this module) to the `linker`.
20
///
21
/// # Example
22
///
23
/// ```
24
/// use wasmtime::{Engine, Result, Store, Config};
25
/// use wasmtime::component::{Linker, ResourceTable};
26
/// use wasmtime_wasi::filesystem::{WasiFilesystemCtx, WasiFilesystemCtxView, WasiFilesystemView};
27
///
28
/// fn main() -> Result<()> {
29
/// let mut config = Config::new();
30
/// config.async_support(true);
31
/// config.wasm_component_model_async(true);
32
/// let engine = Engine::new(&config)?;
33
///
34
/// let mut linker = Linker::<MyState>::new(&engine);
35
/// wasmtime_wasi::p3::filesystem::add_to_linker(&mut linker)?;
36
/// // ... add any further functionality to `linker` if desired ...
37
///
38
/// let mut store = Store::new(
39
/// &engine,
40
/// MyState::default(),
41
/// );
42
///
43
/// // ... use `linker` to instantiate within `store` ...
44
///
45
/// Ok(())
46
/// }
47
///
48
/// #[derive(Default)]
49
/// struct MyState {
50
/// filesystem: WasiFilesystemCtx,
51
/// table: ResourceTable,
52
/// }
53
///
54
/// impl WasiFilesystemView for MyState {
55
/// fn filesystem(&mut self) -> WasiFilesystemCtxView<'_> {
56
/// WasiFilesystemCtxView {
57
/// ctx: &mut self.filesystem,
58
/// table: &mut self.table,
59
/// }
60
/// }
61
/// }
62
/// ```
63
pub fn add_to_linker<T>(linker: &mut Linker<T>) -> wasmtime::Result<()>
64
where
65
T: WasiFilesystemView + 'static,
66
{
67
types::add_to_linker::<_, WasiFilesystem>(linker, T::filesystem)?;
68
preopens::add_to_linker::<_, WasiFilesystem>(linker, T::filesystem)?;
69
Ok(())
70
}
71
72
impl<'a> From<&'a std::io::Error> for types::ErrorCode {
73
fn from(err: &'a std::io::Error) -> Self {
74
crate::filesystem::ErrorCode::from(err).into()
75
}
76
}
77
78
impl From<std::io::Error> for types::ErrorCode {
79
fn from(err: std::io::Error) -> Self {
80
Self::from(&err)
81
}
82
}
83
84
impl From<std::io::Error> for FilesystemError {
85
fn from(error: std::io::Error) -> Self {
86
types::ErrorCode::from(error).into()
87
}
88
}
89
90
impl From<crate::filesystem::ErrorCode> for types::ErrorCode {
91
fn from(error: crate::filesystem::ErrorCode) -> Self {
92
match error {
93
crate::filesystem::ErrorCode::Access => Self::Access,
94
crate::filesystem::ErrorCode::Already => Self::Already,
95
crate::filesystem::ErrorCode::BadDescriptor => Self::BadDescriptor,
96
crate::filesystem::ErrorCode::Busy => Self::Busy,
97
crate::filesystem::ErrorCode::Exist => Self::Exist,
98
crate::filesystem::ErrorCode::FileTooLarge => Self::FileTooLarge,
99
crate::filesystem::ErrorCode::IllegalByteSequence => Self::IllegalByteSequence,
100
crate::filesystem::ErrorCode::InProgress => Self::InProgress,
101
crate::filesystem::ErrorCode::Interrupted => Self::Interrupted,
102
crate::filesystem::ErrorCode::Invalid => Self::Invalid,
103
crate::filesystem::ErrorCode::Io => Self::Io,
104
crate::filesystem::ErrorCode::IsDirectory => Self::IsDirectory,
105
crate::filesystem::ErrorCode::Loop => Self::Loop,
106
crate::filesystem::ErrorCode::TooManyLinks => Self::TooManyLinks,
107
crate::filesystem::ErrorCode::NameTooLong => Self::NameTooLong,
108
crate::filesystem::ErrorCode::NoEntry => Self::NoEntry,
109
crate::filesystem::ErrorCode::InsufficientMemory => Self::InsufficientMemory,
110
crate::filesystem::ErrorCode::InsufficientSpace => Self::InsufficientSpace,
111
crate::filesystem::ErrorCode::NotDirectory => Self::NotDirectory,
112
crate::filesystem::ErrorCode::NotEmpty => Self::NotEmpty,
113
crate::filesystem::ErrorCode::Unsupported => Self::Unsupported,
114
crate::filesystem::ErrorCode::Overflow => Self::Overflow,
115
crate::filesystem::ErrorCode::NotPermitted => Self::NotPermitted,
116
crate::filesystem::ErrorCode::Pipe => Self::Pipe,
117
crate::filesystem::ErrorCode::InvalidSeek => Self::InvalidSeek,
118
}
119
}
120
}
121
122
impl From<crate::filesystem::ErrorCode> for FilesystemError {
123
fn from(error: crate::filesystem::ErrorCode) -> Self {
124
types::ErrorCode::from(error).into()
125
}
126
}
127
128
impl From<wasmtime::component::ResourceTableError> for FilesystemError {
129
fn from(error: wasmtime::component::ResourceTableError) -> Self {
130
Self::trap(error)
131
}
132
}
133
134
impl From<types::Advice> for system_interface::fs::Advice {
135
fn from(advice: types::Advice) -> Self {
136
match advice {
137
types::Advice::Normal => Self::Normal,
138
types::Advice::Sequential => Self::Sequential,
139
types::Advice::Random => Self::Random,
140
types::Advice::WillNeed => Self::WillNeed,
141
types::Advice::DontNeed => Self::DontNeed,
142
types::Advice::NoReuse => Self::NoReuse,
143
}
144
}
145
}
146
147
impl From<types::OpenFlags> for crate::filesystem::OpenFlags {
148
fn from(flags: types::OpenFlags) -> Self {
149
let mut out = Self::empty();
150
if flags.contains(types::OpenFlags::CREATE) {
151
out |= Self::CREATE;
152
}
153
if flags.contains(types::OpenFlags::DIRECTORY) {
154
out |= Self::DIRECTORY;
155
}
156
if flags.contains(types::OpenFlags::EXCLUSIVE) {
157
out |= Self::EXCLUSIVE;
158
}
159
if flags.contains(types::OpenFlags::TRUNCATE) {
160
out |= Self::TRUNCATE;
161
}
162
out
163
}
164
}
165
166
impl From<types::PathFlags> for crate::filesystem::PathFlags {
167
fn from(flags: types::PathFlags) -> Self {
168
let mut out = Self::empty();
169
if flags.contains(types::PathFlags::SYMLINK_FOLLOW) {
170
out |= Self::SYMLINK_FOLLOW;
171
}
172
out
173
}
174
}
175
176
impl From<crate::filesystem::DescriptorFlags> for types::DescriptorFlags {
177
fn from(flags: crate::filesystem::DescriptorFlags) -> Self {
178
let mut out = Self::empty();
179
if flags.contains(crate::filesystem::DescriptorFlags::READ) {
180
out |= Self::READ;
181
}
182
if flags.contains(crate::filesystem::DescriptorFlags::WRITE) {
183
out |= Self::WRITE;
184
}
185
if flags.contains(crate::filesystem::DescriptorFlags::FILE_INTEGRITY_SYNC) {
186
out |= Self::FILE_INTEGRITY_SYNC;
187
}
188
if flags.contains(crate::filesystem::DescriptorFlags::DATA_INTEGRITY_SYNC) {
189
out |= Self::DATA_INTEGRITY_SYNC;
190
}
191
if flags.contains(crate::filesystem::DescriptorFlags::REQUESTED_WRITE_SYNC) {
192
out |= Self::REQUESTED_WRITE_SYNC;
193
}
194
if flags.contains(crate::filesystem::DescriptorFlags::MUTATE_DIRECTORY) {
195
out |= Self::MUTATE_DIRECTORY;
196
}
197
out
198
}
199
}
200
201
impl From<types::DescriptorFlags> for crate::filesystem::DescriptorFlags {
202
fn from(flags: types::DescriptorFlags) -> Self {
203
let mut out = Self::empty();
204
if flags.contains(types::DescriptorFlags::READ) {
205
out |= Self::READ;
206
}
207
if flags.contains(types::DescriptorFlags::WRITE) {
208
out |= Self::WRITE;
209
}
210
if flags.contains(types::DescriptorFlags::FILE_INTEGRITY_SYNC) {
211
out |= Self::FILE_INTEGRITY_SYNC;
212
}
213
if flags.contains(types::DescriptorFlags::DATA_INTEGRITY_SYNC) {
214
out |= Self::DATA_INTEGRITY_SYNC;
215
}
216
if flags.contains(types::DescriptorFlags::REQUESTED_WRITE_SYNC) {
217
out |= Self::REQUESTED_WRITE_SYNC;
218
}
219
if flags.contains(types::DescriptorFlags::MUTATE_DIRECTORY) {
220
out |= Self::MUTATE_DIRECTORY;
221
}
222
out
223
}
224
}
225
226
impl From<crate::filesystem::MetadataHashValue> for types::MetadataHashValue {
227
fn from(
228
crate::filesystem::MetadataHashValue { lower, upper }: crate::filesystem::MetadataHashValue,
229
) -> Self {
230
Self { lower, upper }
231
}
232
}
233
234
impl From<crate::filesystem::DescriptorStat> for types::DescriptorStat {
235
fn from(
236
crate::filesystem::DescriptorStat {
237
type_,
238
link_count,
239
size,
240
data_access_timestamp,
241
data_modification_timestamp,
242
status_change_timestamp,
243
}: crate::filesystem::DescriptorStat,
244
) -> Self {
245
Self {
246
type_: type_.into(),
247
link_count,
248
size,
249
data_access_timestamp: data_access_timestamp.map(Into::into),
250
data_modification_timestamp: data_modification_timestamp.map(Into::into),
251
status_change_timestamp: status_change_timestamp.map(Into::into),
252
}
253
}
254
}
255
256
impl From<crate::filesystem::DescriptorType> for types::DescriptorType {
257
fn from(ty: crate::filesystem::DescriptorType) -> Self {
258
match ty {
259
crate::filesystem::DescriptorType::Unknown => Self::Unknown,
260
crate::filesystem::DescriptorType::BlockDevice => Self::BlockDevice,
261
crate::filesystem::DescriptorType::CharacterDevice => Self::CharacterDevice,
262
crate::filesystem::DescriptorType::Directory => Self::Directory,
263
crate::filesystem::DescriptorType::SymbolicLink => Self::SymbolicLink,
264
crate::filesystem::DescriptorType::RegularFile => Self::RegularFile,
265
}
266
}
267
}
268
269
impl From<cap_std::fs::FileType> for types::DescriptorType {
270
fn from(ft: cap_std::fs::FileType) -> Self {
271
use cap_fs_ext::FileTypeExt as _;
272
if ft.is_dir() {
273
Self::Directory
274
} else if ft.is_symlink() {
275
Self::SymbolicLink
276
} else if ft.is_block_device() {
277
Self::BlockDevice
278
} else if ft.is_char_device() {
279
Self::CharacterDevice
280
} else if ft.is_file() {
281
Self::RegularFile
282
} else {
283
Self::Unknown
284
}
285
}
286
}
287
288