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:
May B
2022-11-02 20:27:17 +01:00
committed by GitHub
parent 961107ec63
commit 348f962d23
4 changed files with 84 additions and 40 deletions

1
Cargo.lock generated
View File

@@ -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",

View File

@@ -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"]

View File

@@ -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.

View File

@@ -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]