mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-28 08:01:33 +00:00
add execvp
This commit is contained in:
40
lib/emscripten/src/exec.rs
Normal file
40
lib/emscripten/src/exec.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use libc::execvp;
|
||||
use std::cell::Cell;
|
||||
use std::ffi::CString;
|
||||
use wasmer_runtime_core::vm::Ctx;
|
||||
|
||||
pub fn _execvp(ctx: &mut Ctx, command_name_offset: u32, argv_offset: u32) -> i32 {
|
||||
// a single reference to re-use
|
||||
let emscripten_memory = ctx.memory(0);
|
||||
|
||||
// read command name as string
|
||||
let command_name_string_vec: Vec<u8> = emscripten_memory.view()
|
||||
[(command_name_offset as usize)..]
|
||||
.iter()
|
||||
.map(|cell| cell.get())
|
||||
.take_while(|&byte| byte != 0)
|
||||
.collect();
|
||||
let command_name_string = CString::new(command_name_string_vec).unwrap();
|
||||
|
||||
// get the array of args
|
||||
let mut argv: Vec<*const i8> = emscripten_memory.view()[((argv_offset / 4) as usize)..]
|
||||
.iter()
|
||||
.map(|cell: &Cell<u32>| cell.get())
|
||||
.take_while(|&byte| byte != 0)
|
||||
.map(|offset| {
|
||||
let p: *const i8 = (emscripten_memory.view::<u8>()[(offset as usize)..])
|
||||
.iter()
|
||||
.map(|cell| cell.as_ptr() as *const i8)
|
||||
.collect::<Vec<*const i8>>()[0];
|
||||
p
|
||||
})
|
||||
.collect();
|
||||
|
||||
// push a nullptr on to the end of the args array
|
||||
argv.push(std::ptr::null());
|
||||
|
||||
// construct raw pointers and hand them to `execvp`
|
||||
let command_pointer = command_name_string.as_ptr() as *const i8;
|
||||
let args_pointer = argv.as_ptr();
|
||||
unsafe { execvp(command_pointer, args_pointer) }
|
||||
}
|
@ -31,6 +31,7 @@ mod emscripten_target;
|
||||
mod env;
|
||||
mod errno;
|
||||
mod exception;
|
||||
mod exec;
|
||||
mod io;
|
||||
mod jmp;
|
||||
mod linking;
|
||||
@ -439,6 +440,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"___unlock" => func!(crate::lock::___unlock),
|
||||
"___wait" => func!(crate::lock::___wait),
|
||||
|
||||
// exec
|
||||
"_execvp" => func!(crate::exec::_execvp),
|
||||
|
||||
// Env
|
||||
"___assert_fail" => func!(crate::env::___assert_fail),
|
||||
"_getenv" => func!(crate::env::_getenv),
|
||||
|
Reference in New Issue
Block a user