c-api: add wasi_config_set_stdin_bytes (#5179)
* c-api: use enums for wasi_config_t stdio pipes * c-api: add wasi_config_set_stdin_bytes Co-authored-by: Shu <me@wadza.fr>
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -3426,6 +3426,7 @@ dependencies = [
|
|||||||
"env_logger 0.9.0",
|
"env_logger 0.9.0",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"wasi-cap-std-sync",
|
"wasi-cap-std-sync",
|
||||||
|
"wasi-common",
|
||||||
"wasmtime",
|
"wasmtime",
|
||||||
"wasmtime-c-api-macros",
|
"wasmtime-c-api-macros",
|
||||||
"wasmtime-wasi",
|
"wasmtime-wasi",
|
||||||
|
|||||||
@@ -30,11 +30,12 @@ wat = { workspace = true, optional = true }
|
|||||||
wasi-cap-std-sync = { workspace = true, optional = true }
|
wasi-cap-std-sync = { workspace = true, optional = true }
|
||||||
wasmtime-wasi = { workspace = true, optional = true }
|
wasmtime-wasi = { workspace = true, optional = true }
|
||||||
cap-std = { workspace = true, optional = true }
|
cap-std = { workspace = true, optional = true }
|
||||||
|
wasi-common = { workspace = true, optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ['jitdump', 'wat', 'wasi', 'cache', 'parallel-compilation', 'memory-init-cow']
|
default = ['jitdump', 'wat', 'wasi', 'cache', 'parallel-compilation', 'memory-init-cow']
|
||||||
jitdump = ["wasmtime/jitdump"]
|
jitdump = ["wasmtime/jitdump"]
|
||||||
cache = ["wasmtime/cache"]
|
cache = ["wasmtime/cache"]
|
||||||
parallel-compilation = ['wasmtime/parallel-compilation']
|
parallel-compilation = ['wasmtime/parallel-compilation']
|
||||||
wasi = ['wasi-cap-std-sync', 'wasmtime-wasi', 'cap-std']
|
wasi = ['wasi-cap-std-sync', 'wasmtime-wasi', 'cap-std', 'wasi-common']
|
||||||
memory-init-cow = ["wasmtime/memory-init-cow"]
|
memory-init-cow = ["wasmtime/memory-init-cow"]
|
||||||
|
|||||||
@@ -94,6 +94,16 @@ WASI_API_EXTERN void wasi_config_inherit_env(wasi_config_t* config);
|
|||||||
*/
|
*/
|
||||||
WASI_API_EXTERN bool wasi_config_set_stdin_file(wasi_config_t* config, const char* path);
|
WASI_API_EXTERN bool wasi_config_set_stdin_file(wasi_config_t* config, const char* path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Configures standard input to be taken from the specified #wasm_byte_vec_t.
|
||||||
|
*
|
||||||
|
* By default WASI programs have no stdin, but this configures the specified
|
||||||
|
* bytes to be used as stdin for this configuration.
|
||||||
|
*
|
||||||
|
* This function takes ownership of the `binary` argument.
|
||||||
|
*/
|
||||||
|
WASI_API_EXTERN void wasi_config_set_stdin_bytes(wasi_config_t* config, wasm_byte_vec_t* binary);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Configures this process's own stdin stream to be used as stdin for
|
* \brief Configures this process's own stdin stream to be used as stdin for
|
||||||
* this WASI configuration.
|
* this WASI configuration.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//! The WASI embedding API definitions for Wasmtime.
|
//! The WASI embedding API definitions for Wasmtime.
|
||||||
|
|
||||||
|
use crate::wasm_byte_vec_t;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cap_std::ambient_authority;
|
use cap_std::ambient_authority;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
@@ -7,6 +8,7 @@ use std::fs::File;
|
|||||||
use std::os::raw::{c_char, c_int};
|
use std::os::raw::{c_char, c_int};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use wasi_common::pipe::ReadPipe;
|
||||||
use wasmtime_wasi::{
|
use wasmtime_wasi::{
|
||||||
sync::{Dir, WasiCtxBuilder},
|
sync::{Dir, WasiCtxBuilder},
|
||||||
WasiCtx,
|
WasiCtx,
|
||||||
@@ -29,15 +31,31 @@ unsafe fn create_file(path: *const c_char) -> Option<File> {
|
|||||||
pub struct wasi_config_t {
|
pub struct wasi_config_t {
|
||||||
args: Vec<Vec<u8>>,
|
args: Vec<Vec<u8>>,
|
||||||
env: Vec<(Vec<u8>, Vec<u8>)>,
|
env: Vec<(Vec<u8>, Vec<u8>)>,
|
||||||
stdin: Option<File>,
|
stdin: WasiConfigReadPipe,
|
||||||
stdout: Option<File>,
|
stdout: WasiConfigWritePipe,
|
||||||
stderr: Option<File>,
|
stderr: WasiConfigWritePipe,
|
||||||
preopens: Vec<(Dir, PathBuf)>,
|
preopens: Vec<(Dir, PathBuf)>,
|
||||||
inherit_args: bool,
|
inherit_args: bool,
|
||||||
inherit_env: bool,
|
inherit_env: bool,
|
||||||
inherit_stdin: bool,
|
}
|
||||||
inherit_stdout: bool,
|
|
||||||
inherit_stderr: bool,
|
#[repr(C)]
|
||||||
|
#[derive(Default)]
|
||||||
|
pub enum WasiConfigReadPipe {
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
Inherit,
|
||||||
|
File(File),
|
||||||
|
Bytes(Vec<u8>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Default)]
|
||||||
|
pub enum WasiConfigWritePipe {
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
Inherit,
|
||||||
|
File(File),
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmtime_c_api_macros::declare_own!(wasi_config_t);
|
wasmtime_c_api_macros::declare_own!(wasi_config_t);
|
||||||
@@ -69,27 +87,37 @@ impl wasi_config_t {
|
|||||||
.collect::<Result<Vec<(String, String)>>>()?;
|
.collect::<Result<Vec<(String, String)>>>()?;
|
||||||
builder = builder.envs(&env)?;
|
builder = builder.envs(&env)?;
|
||||||
}
|
}
|
||||||
if self.inherit_stdin {
|
builder = match self.stdin {
|
||||||
builder = builder.inherit_stdin();
|
WasiConfigReadPipe::None => builder,
|
||||||
} else if let Some(file) = self.stdin {
|
WasiConfigReadPipe::Inherit => builder.inherit_stdin(),
|
||||||
let file = cap_std::fs::File::from_std(file);
|
WasiConfigReadPipe::File(file) => {
|
||||||
let file = wasi_cap_std_sync::file::File::from_cap_std(file);
|
let file = cap_std::fs::File::from_std(file);
|
||||||
builder = builder.stdin(Box::new(file));
|
let file = wasi_cap_std_sync::file::File::from_cap_std(file);
|
||||||
}
|
builder.stdin(Box::new(file))
|
||||||
if self.inherit_stdout {
|
}
|
||||||
builder = builder.inherit_stdout();
|
WasiConfigReadPipe::Bytes(binary) => {
|
||||||
} else if let Some(file) = self.stdout {
|
let binary = ReadPipe::from(binary);
|
||||||
let file = cap_std::fs::File::from_std(file);
|
builder.stdin(Box::new(binary))
|
||||||
let file = wasi_cap_std_sync::file::File::from_cap_std(file);
|
}
|
||||||
builder = builder.stdout(Box::new(file));
|
};
|
||||||
}
|
builder = match self.stdout {
|
||||||
if self.inherit_stderr {
|
WasiConfigWritePipe::None => builder,
|
||||||
builder = builder.inherit_stderr();
|
WasiConfigWritePipe::Inherit => builder.inherit_stdout(),
|
||||||
} else if let Some(file) = self.stderr {
|
WasiConfigWritePipe::File(file) => {
|
||||||
let file = cap_std::fs::File::from_std(file);
|
let file = cap_std::fs::File::from_std(file);
|
||||||
let file = wasi_cap_std_sync::file::File::from_cap_std(file);
|
let file = wasi_cap_std_sync::file::File::from_cap_std(file);
|
||||||
builder = builder.stderr(Box::new(file));
|
builder.stdout(Box::new(file))
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
builder = match self.stderr {
|
||||||
|
WasiConfigWritePipe::None => builder,
|
||||||
|
WasiConfigWritePipe::Inherit => builder.inherit_stderr(),
|
||||||
|
WasiConfigWritePipe::File(file) => {
|
||||||
|
let file = cap_std::fs::File::from_std(file);
|
||||||
|
let file = wasi_cap_std_sync::file::File::from_cap_std(file);
|
||||||
|
builder.stderr(Box::new(file))
|
||||||
|
}
|
||||||
|
};
|
||||||
for (dir, path) in self.preopens {
|
for (dir, path) in self.preopens {
|
||||||
builder = builder.preopened_dir(dir, path)?;
|
builder = builder.preopened_dir(dir, path)?;
|
||||||
}
|
}
|
||||||
@@ -159,16 +187,24 @@ pub unsafe extern "C" fn wasi_config_set_stdin_file(
|
|||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
config.stdin = Some(file);
|
config.stdin = WasiConfigReadPipe::File(file);
|
||||||
config.inherit_stdin = false;
|
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasi_config_set_stdin_bytes(
|
||||||
|
config: &mut wasi_config_t,
|
||||||
|
binary: &mut wasm_byte_vec_t,
|
||||||
|
) {
|
||||||
|
let binary = binary.take();
|
||||||
|
|
||||||
|
config.stdin = WasiConfigReadPipe::Bytes(binary);
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasi_config_inherit_stdin(config: &mut wasi_config_t) {
|
pub extern "C" fn wasi_config_inherit_stdin(config: &mut wasi_config_t) {
|
||||||
config.stdin = None;
|
config.stdin = WasiConfigReadPipe::Inherit;
|
||||||
config.inherit_stdin = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -181,16 +217,14 @@ pub unsafe extern "C" fn wasi_config_set_stdout_file(
|
|||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
config.stdout = Some(file);
|
config.stdout = WasiConfigWritePipe::File(file);
|
||||||
config.inherit_stdout = false;
|
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasi_config_inherit_stdout(config: &mut wasi_config_t) {
|
pub extern "C" fn wasi_config_inherit_stdout(config: &mut wasi_config_t) {
|
||||||
config.stdout = None;
|
config.stdout = WasiConfigWritePipe::Inherit;
|
||||||
config.inherit_stdout = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -203,16 +237,14 @@ pub unsafe extern "C" fn wasi_config_set_stderr_file(
|
|||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
(*config).stderr = Some(file);
|
config.stderr = WasiConfigWritePipe::File(file);
|
||||||
(*config).inherit_stderr = false;
|
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasi_config_inherit_stderr(config: &mut wasi_config_t) {
|
pub extern "C" fn wasi_config_inherit_stderr(config: &mut wasi_config_t) {
|
||||||
config.stderr = None;
|
config.stderr = WasiConfigWritePipe::Inherit;
|
||||||
config.inherit_stderr = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
Reference in New Issue
Block a user