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