Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/c-api/src/wasi.rs
1692 views
1
//! The WASI embedding API definitions for Wasmtime.
2
3
use crate::wasm_byte_vec_t;
4
use anyhow::Result;
5
use std::ffi::{CStr, c_char};
6
use std::fs::File;
7
use std::path::Path;
8
use std::slice;
9
use wasmtime_wasi::WasiCtxBuilder;
10
use wasmtime_wasi::p1::WasiP1Ctx;
11
12
unsafe fn cstr_to_path<'a>(path: *const c_char) -> Option<&'a Path> {
13
CStr::from_ptr(path).to_str().map(Path::new).ok()
14
}
15
16
unsafe fn cstr_to_str<'a>(s: *const c_char) -> Option<&'a str> {
17
CStr::from_ptr(s).to_str().ok()
18
}
19
20
unsafe fn open_file(path: *const c_char) -> Option<File> {
21
File::open(cstr_to_path(path)?).ok()
22
}
23
24
unsafe fn create_file(path: *const c_char) -> Option<File> {
25
File::create(cstr_to_path(path)?).ok()
26
}
27
28
#[repr(C)]
29
pub struct wasi_config_t {
30
builder: WasiCtxBuilder,
31
}
32
33
wasmtime_c_api_macros::declare_own!(wasi_config_t);
34
35
impl wasi_config_t {
36
pub fn into_wasi_ctx(mut self) -> Result<WasiP1Ctx> {
37
Ok(self.builder.build_p1())
38
}
39
}
40
41
#[unsafe(no_mangle)]
42
pub extern "C" fn wasi_config_new() -> Box<wasi_config_t> {
43
Box::new(wasi_config_t {
44
builder: WasiCtxBuilder::new(),
45
})
46
}
47
48
#[unsafe(no_mangle)]
49
pub unsafe extern "C" fn wasi_config_set_argv(
50
config: &mut wasi_config_t,
51
argc: usize,
52
argv: *const *const c_char,
53
) -> bool {
54
for arg in slice::from_raw_parts(argv, argc) {
55
let arg = match CStr::from_ptr(*arg).to_str() {
56
Ok(s) => s,
57
Err(_) => return false,
58
};
59
config.builder.arg(arg);
60
}
61
true
62
}
63
64
#[unsafe(no_mangle)]
65
pub extern "C" fn wasi_config_inherit_argv(config: &mut wasi_config_t) {
66
config.builder.inherit_args();
67
}
68
69
#[unsafe(no_mangle)]
70
pub unsafe extern "C" fn wasi_config_set_env(
71
config: &mut wasi_config_t,
72
envc: usize,
73
names: *const *const c_char,
74
values: *const *const c_char,
75
) -> bool {
76
let names = slice::from_raw_parts(names, envc);
77
let values = slice::from_raw_parts(values, envc);
78
79
for (k, v) in names.iter().zip(values) {
80
let k = match cstr_to_str(*k) {
81
Some(s) => s,
82
None => return false,
83
};
84
let v = match cstr_to_str(*v) {
85
Some(s) => s,
86
None => return false,
87
};
88
config.builder.env(k, v);
89
}
90
true
91
}
92
93
#[unsafe(no_mangle)]
94
pub extern "C" fn wasi_config_inherit_env(config: &mut wasi_config_t) {
95
config.builder.inherit_env();
96
}
97
98
#[unsafe(no_mangle)]
99
pub unsafe extern "C" fn wasi_config_set_stdin_file(
100
config: &mut wasi_config_t,
101
path: *const c_char,
102
) -> bool {
103
let file = match open_file(path) {
104
Some(f) => f,
105
None => return false,
106
};
107
108
let file = tokio::fs::File::from_std(file);
109
let stdin_stream = wasmtime_wasi::cli::AsyncStdinStream::new(file);
110
config.builder.stdin(stdin_stream);
111
112
true
113
}
114
115
#[unsafe(no_mangle)]
116
pub unsafe extern "C" fn wasi_config_set_stdin_bytes(
117
config: &mut wasi_config_t,
118
binary: &mut wasm_byte_vec_t,
119
) {
120
let binary = binary.take();
121
let binary = wasmtime_wasi::p2::pipe::MemoryInputPipe::new(binary);
122
config.builder.stdin(binary);
123
}
124
125
#[unsafe(no_mangle)]
126
pub extern "C" fn wasi_config_inherit_stdin(config: &mut wasi_config_t) {
127
config.builder.inherit_stdin();
128
}
129
130
#[unsafe(no_mangle)]
131
pub unsafe extern "C" fn wasi_config_set_stdout_file(
132
config: &mut wasi_config_t,
133
path: *const c_char,
134
) -> bool {
135
let file = match create_file(path) {
136
Some(f) => f,
137
None => return false,
138
};
139
140
config
141
.builder
142
.stdout(wasmtime_wasi::cli::OutputFile::new(file));
143
144
true
145
}
146
147
#[unsafe(no_mangle)]
148
pub extern "C" fn wasi_config_inherit_stdout(config: &mut wasi_config_t) {
149
config.builder.inherit_stdout();
150
}
151
152
#[unsafe(no_mangle)]
153
pub unsafe extern "C" fn wasi_config_set_stderr_file(
154
config: &mut wasi_config_t,
155
path: *const c_char,
156
) -> bool {
157
let file = match create_file(path) {
158
Some(f) => f,
159
None => return false,
160
};
161
162
config
163
.builder
164
.stderr(wasmtime_wasi::cli::OutputFile::new(file));
165
166
true
167
}
168
169
#[unsafe(no_mangle)]
170
pub extern "C" fn wasi_config_inherit_stderr(config: &mut wasi_config_t) {
171
config.builder.inherit_stderr();
172
}
173
174
#[unsafe(no_mangle)]
175
pub unsafe extern "C" fn wasi_config_preopen_dir(
176
config: &mut wasi_config_t,
177
path: *const c_char,
178
guest_path: *const c_char,
179
dir_perms: usize,
180
file_perms: usize,
181
) -> bool {
182
let guest_path = match cstr_to_str(guest_path) {
183
Some(p) => p,
184
None => return false,
185
};
186
187
let host_path = match cstr_to_path(path) {
188
Some(p) => p,
189
None => return false,
190
};
191
192
let dir_perms = match wasmtime_wasi::DirPerms::from_bits(dir_perms) {
193
Some(p) => p,
194
None => return false,
195
};
196
197
let file_perms = match wasmtime_wasi::FilePerms::from_bits(file_perms) {
198
Some(p) => p,
199
None => return false,
200
};
201
202
config
203
.builder
204
.preopened_dir(host_path, guest_path, dir_perms, file_perms)
205
.is_ok()
206
}
207
208