mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 21:28:21 +00:00
Added intial API for creating two-channel pipes
This commit is contained in:
@@ -314,6 +314,21 @@ unsafe extern "C" fn wasi_console_out_read_memory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn wasi_console_out_read_memory_2(
|
||||||
|
ptr: *const c_void, /* = *WasiPipe */
|
||||||
|
byte_ptr: *mut c_char, /* &[u8] bytes to read */
|
||||||
|
max_bytes: usize, /* max bytes to read */
|
||||||
|
) -> i64 {
|
||||||
|
use std::io::Read;
|
||||||
|
let ptr = ptr as *mut WasiPipe;
|
||||||
|
let ptr = &mut *ptr;
|
||||||
|
let slice = std::slice::from_raw_parts_mut(byte_ptr as *mut u8, max_bytes);
|
||||||
|
match ptr.read(slice) {
|
||||||
|
Ok(o) => o as i64,
|
||||||
|
Err(_) => -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn wasi_console_out_write_memory(
|
unsafe extern "C" fn wasi_console_out_write_memory(
|
||||||
ptr: *const c_void, /* = *WasiPipePair */
|
ptr: *const c_void, /* = *WasiPipePair */
|
||||||
byte_ptr: *const c_char,
|
byte_ptr: *const c_char,
|
||||||
@@ -339,6 +354,31 @@ unsafe extern "C" fn wasi_console_out_write_memory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn wasi_console_out_write_memory_2(
|
||||||
|
ptr: *const c_void, /* = *WasiPipe */
|
||||||
|
byte_ptr: *const c_char,
|
||||||
|
byte_len: usize,
|
||||||
|
flush: bool,
|
||||||
|
) -> i64 {
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
let ptr = ptr as *mut WasiPipe;
|
||||||
|
let ptr = &mut *ptr;
|
||||||
|
|
||||||
|
if flush {
|
||||||
|
match ptr.flush() {
|
||||||
|
Ok(()) => 0,
|
||||||
|
Err(_) => -1,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let slice = std::slice::from_raw_parts(byte_ptr as *const u8, byte_len);
|
||||||
|
match ptr.write(slice) {
|
||||||
|
Ok(o) => o as i64,
|
||||||
|
Err(_) => -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn wasi_console_out_seek_memory(
|
unsafe extern "C" fn wasi_console_out_seek_memory(
|
||||||
ptr: *const c_void, /* = *WasiPipePair */
|
ptr: *const c_void, /* = *WasiPipePair */
|
||||||
direction: c_char,
|
direction: c_char,
|
||||||
@@ -364,20 +404,82 @@ unsafe extern "C" fn wasi_console_out_seek_memory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsafe extern "C" fn wasi_console_out_seek_memory_2(
|
||||||
|
ptr: *const c_void, /* = *WasiPipe */
|
||||||
|
direction: c_char,
|
||||||
|
seek_to: i64,
|
||||||
|
) -> i64 {
|
||||||
|
use std::io::Seek;
|
||||||
|
|
||||||
|
let ptr = ptr as *mut WasiPipe;
|
||||||
|
let ptr = &mut *ptr;
|
||||||
|
|
||||||
|
let seek_from = match direction {
|
||||||
|
0 => std::io::SeekFrom::Start(seek_to.max(0) as u64),
|
||||||
|
1 => std::io::SeekFrom::End(seek_to),
|
||||||
|
2 => std::io::SeekFrom::Current(seek_to),
|
||||||
|
_ => {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match ptr.seek(seek_from) {
|
||||||
|
Ok(o) => o as i64,
|
||||||
|
Err(_) => -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn wasi_console_out_delete_memory(ptr: *const c_void, /* = *WasiPipe */) -> i64 {
|
unsafe extern "C" fn wasi_console_out_delete_memory(ptr: *const c_void, /* = *WasiPipe */) -> i64 {
|
||||||
let ptr = ptr as *const WasiPipePair;
|
let ptr = ptr as *const WasiPipePair;
|
||||||
let _: WasiPipePair = std::mem::transmute_copy(&*ptr); // dropped here, destructors run here
|
let _: WasiPipePair = std::mem::transmute_copy(&*ptr); // dropped here, destructors run here
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn wasi_console_out_delete_memory_2(ptr: *const c_void, /* = *WasiPipe */) -> i64 {
|
||||||
|
let ptr = ptr as *const WasiPipe;
|
||||||
|
let _: WasiPipe = std::mem::transmute_copy(&*ptr); // dropped here, destructors run here
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasi_pipe_new_2(ptr_user: &mut *mut wasi_console_out_t) -> *mut wasi_console_out_t {
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
|
|
||||||
|
let pair = WasiPipe::new();
|
||||||
|
|
||||||
|
let mut data1 = ManuallyDrop::new(pair.send);
|
||||||
|
let ptr1: &mut WasiPipe = &mut data1;
|
||||||
|
|
||||||
|
*ptr_user = wasi_console_out_new(
|
||||||
|
wasi_console_out_read_memory_2,
|
||||||
|
wasi_console_out_write_memory_2,
|
||||||
|
wasi_console_out_seek_memory_2,
|
||||||
|
wasi_console_out_delete_memory_2,
|
||||||
|
ptr1 as *mut _ as *mut c_void,
|
||||||
|
std::mem::size_of::<WasiPipe>(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut data2 = ManuallyDrop::new(pair.recv);
|
||||||
|
let ptr2: &mut WasiPipe = &mut data2;
|
||||||
|
wasi_console_out_new(
|
||||||
|
wasi_console_out_read_memory_2,
|
||||||
|
wasi_console_out_write_memory_2,
|
||||||
|
wasi_console_out_seek_memory_2,
|
||||||
|
wasi_console_out_delete_memory_2,
|
||||||
|
ptr2 as *mut _ as *mut c_void,
|
||||||
|
std::mem::size_of::<WasiPipe>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new `wasi_console_out_t` which uses a memory buffer
|
/// Creates a new `wasi_console_out_t` which uses a memory buffer
|
||||||
/// for backing stdin / stdout / stderr
|
/// for backing stdin / stdout / stderr
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasi_pipe_new() -> *mut wasi_console_out_t {
|
pub unsafe extern "C" fn wasi_pipe_new() -> *mut wasi_console_out_t {
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
|
|
||||||
let (send, recv) = WasiPipe::new();
|
let pair = WasiPipe::new();
|
||||||
let pair = WasiPipePair { send, recv };
|
|
||||||
let mut data = ManuallyDrop::new(pair);
|
let mut data = ManuallyDrop::new(pair);
|
||||||
let ptr: &mut WasiPipePair = &mut data;
|
let ptr: &mut WasiPipePair = &mut data;
|
||||||
|
|
||||||
@@ -1205,6 +1307,38 @@ mod tests {
|
|||||||
.success();
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wasi_stdin_set() {
|
||||||
|
(assert_c! {
|
||||||
|
#include "tests/wasmer.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
wasi_console_out_t* override_stdout_1 = NULL;
|
||||||
|
wasi_console_out_t* override_stdout_2 = wasi_pipe_new_2(&override_stdout_1);
|
||||||
|
|
||||||
|
assert(override_stdout_1);
|
||||||
|
assert(override_stdout_2);
|
||||||
|
|
||||||
|
// write to override_stdout_1, then close override_stdout_1
|
||||||
|
wasi_console_out_write_str(override_stdout_1, "test");
|
||||||
|
wasi_console_out_delete(override_stdout_1);
|
||||||
|
|
||||||
|
// read from override_stdout_2, after override_stdout_1 has been closed so it doesn't block
|
||||||
|
char* out;
|
||||||
|
wasi_console_out_read_str(override_stdout_2, &out);
|
||||||
|
assert(strcmp(out, "test") == 0);
|
||||||
|
wasi_console_out_delete_str(out);
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
wasi_console_out_delete(override_stdout_2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}).success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wasi_stdin_set() {
|
fn test_wasi_stdin_set() {
|
||||||
(assert_c! {
|
(assert_c! {
|
||||||
@@ -1392,4 +1526,6 @@ mod tests {
|
|||||||
})
|
})
|
||||||
.success();
|
.success();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user