2019-03-21 10:20:59 -07:00
|
|
|
use crate::varargs::VarArgs;
|
|
|
|
|
|
|
|
#[cfg(not(feature = "vfs"))]
|
|
|
|
pub mod host_fs;
|
|
|
|
|
|
|
|
#[cfg(feature = "vfs")]
|
|
|
|
pub mod vfs;
|
|
|
|
|
|
|
|
#[cfg(not(feature = "vfs"))]
|
|
|
|
pub use host_fs::*;
|
|
|
|
|
|
|
|
#[cfg(feature = "vfs")]
|
|
|
|
pub use vfs::*;
|
|
|
|
|
|
|
|
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
|
|
|
|
/// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html
|
2019-03-21 11:00:49 -07:00
|
|
|
use libc::{c_int, dup2, fcntl, pid_t, rusage, setpgid, uname, utsname, EINVAL, F_GETFD, F_SETFD};
|
2019-03-21 10:20:59 -07:00
|
|
|
use wasmer_runtime_core::vm::Ctx;
|
|
|
|
|
|
|
|
// Linking to functions that are not provided by rust libc
|
|
|
|
#[cfg(target_os = "macos")]
|
|
|
|
#[link(name = "c")]
|
|
|
|
extern "C" {
|
|
|
|
pub fn wait4(pid: pid_t, status: *mut c_int, options: c_int, rusage: *mut rusage) -> pid_t;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(target_os = "macos"))]
|
|
|
|
use libc::wait4;
|
|
|
|
|
|
|
|
// Another conditional constant for name resolution: Macos et iOS use
|
|
|
|
// SO_NOSIGPIPE as a setsockopt flag to disable SIGPIPE emission on socket.
|
|
|
|
// Other platforms do otherwise.
|
|
|
|
//#[cfg(target_os = "darwin")]
|
|
|
|
//use libc::SO_NOSIGPIPE;
|
|
|
|
//#[cfg(not(target_os = "darwin"))]
|
|
|
|
//const SO_NOSIGPIPE: c_int = 0;
|
|
|
|
|
|
|
|
// getgid
|
|
|
|
//#[cfg(not(feature = "vfs"))]
|
|
|
|
pub fn ___syscall201(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
|
|
|
debug!("emscripten::___syscall201 (getgid)");
|
|
|
|
let result = unsafe {
|
|
|
|
// Maybe fix: Emscripten returns 0 always
|
2019-03-21 11:00:49 -07:00
|
|
|
libc::getgid() as i32
|
2019-03-21 10:20:59 -07:00
|
|
|
};
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
|
|
|
// getgid32
|
|
|
|
pub fn ___syscall202(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
|
|
|
// gid_t
|
|
|
|
debug!("emscripten::___syscall202 (getgid32)");
|
|
|
|
unsafe {
|
|
|
|
// Maybe fix: Emscripten returns 0 always
|
2019-03-21 11:00:49 -07:00
|
|
|
libc::getgid() as _
|
2019-03-21 10:20:59 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// wait4
|
|
|
|
#[allow(clippy::cast_ptr_alignment)]
|
|
|
|
pub fn ___syscall114(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> pid_t {
|
|
|
|
debug!("emscripten::___syscall114 (wait4)");
|
|
|
|
let pid: pid_t = varargs.get(ctx);
|
|
|
|
let status: u32 = varargs.get(ctx);
|
|
|
|
let options: c_int = varargs.get(ctx);
|
|
|
|
let rusage: u32 = varargs.get(ctx);
|
|
|
|
let status_addr = emscripten_memory_pointer!(ctx.memory(0), status) as *mut c_int;
|
|
|
|
let rusage_addr = emscripten_memory_pointer!(ctx.memory(0), rusage) as *mut rusage;
|
|
|
|
let res = unsafe { wait4(pid, status_addr, options, rusage_addr) };
|
|
|
|
debug!(
|
|
|
|
"=> pid: {}, status: {:?}, options: {}, rusage: {:?} = pid: {}",
|
|
|
|
pid, status_addr, options, rusage_addr, res
|
|
|
|
);
|
|
|
|
res
|
|
|
|
}
|
|
|
|
|
|
|
|
/// setpgid
|
|
|
|
pub fn ___syscall57(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
|
|
|
debug!("emscripten::___syscall57 (setpgid) {}", _which);
|
|
|
|
let pid: i32 = varargs.get(ctx);
|
|
|
|
let pgid: i32 = varargs.get(ctx);
|
|
|
|
unsafe { setpgid(pid, pgid) }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// uname
|
|
|
|
// NOTE: Wondering if we should return custom utsname, like Emscripten.
|
|
|
|
pub fn ___syscall122(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
|
|
|
debug!("emscripten::___syscall122 (uname) {}", _which);
|
|
|
|
let buf: u32 = varargs.get(ctx);
|
|
|
|
debug!("=> buf: {}", buf);
|
|
|
|
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut utsname;
|
|
|
|
unsafe { uname(buf_addr) }
|
|
|
|
}
|
2019-03-21 11:00:49 -07:00
|
|
|
|
|
|
|
/// chown
|
|
|
|
pub fn ___syscall212(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
|
|
|
debug!("emscripten::___syscall212 (chown) {}", _which);
|
|
|
|
|
|
|
|
let pathname: u32 = varargs.get(ctx);
|
|
|
|
let owner: u32 = varargs.get(ctx);
|
|
|
|
let group: u32 = varargs.get(ctx);
|
|
|
|
|
|
|
|
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
|
|
|
|
|
|
|
unsafe { libc::chown(pathname_addr, owner, group) }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// dup3
|
|
|
|
pub fn ___syscall330(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> pid_t {
|
|
|
|
// Implementation based on description at https://linux.die.net/man/2/dup3
|
|
|
|
debug!("emscripten::___syscall330 (dup3)");
|
|
|
|
let oldfd: c_int = varargs.get(ctx);
|
|
|
|
let newfd: c_int = varargs.get(ctx);
|
|
|
|
let flags: c_int = varargs.get(ctx);
|
|
|
|
|
|
|
|
if oldfd == newfd {
|
|
|
|
return EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
let res = unsafe { dup2(oldfd, newfd) };
|
|
|
|
|
|
|
|
// Set flags on newfd (https://www.gnu.org/software/libc/manual/html_node/Descriptor-Flags.html)
|
|
|
|
let mut old_flags = unsafe { fcntl(newfd, F_GETFD, 0) };
|
|
|
|
|
|
|
|
if old_flags > 0 {
|
|
|
|
old_flags |= flags;
|
|
|
|
} else if old_flags == 0 {
|
|
|
|
old_flags &= !flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
fcntl(newfd, F_SETFD, old_flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
debug!(
|
|
|
|
"=> oldfd: {}, newfd: {}, flags: {} = pid: {}",
|
|
|
|
oldfd, newfd, flags, res
|
|
|
|
);
|
|
|
|
res
|
|
|
|
}
|