mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-21 04:31:33 +00:00
fix bugs in em mapdir, improve it for relative paths, use it more
This commit is contained in:
@ -96,9 +96,12 @@ pub fn ___syscall6(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
|
|||||||
pub fn ___syscall12(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall12(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall12 (chdir) {}", _which);
|
debug!("emscripten::___syscall12 (chdir) {}", _which);
|
||||||
let path_ptr = varargs.get_str(ctx);
|
let path_ptr = varargs.get_str(ctx);
|
||||||
let real_path = get_cstr_path(ctx, path_ptr)
|
let real_path_owned = get_cstr_path(ctx, path_ptr);
|
||||||
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
.unwrap_or(path_ptr);
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
path_ptr
|
||||||
|
};
|
||||||
let ret = unsafe { chdir(real_path) };
|
let ret = unsafe { chdir(real_path) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> path: {:?}, ret: {}",
|
"=> path: {:?}, ret: {}",
|
||||||
@ -129,12 +132,18 @@ pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
|
|||||||
debug!("emscripten::___syscall38 (rename)");
|
debug!("emscripten::___syscall38 (rename)");
|
||||||
let old_path = varargs.get_str(ctx);
|
let old_path = varargs.get_str(ctx);
|
||||||
let new_path = varargs.get_str(ctx);
|
let new_path = varargs.get_str(ctx);
|
||||||
let real_old_path = get_cstr_path(ctx, old_path)
|
let real_old_path_owned = get_cstr_path(ctx, old_path);
|
||||||
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
|
let real_old_path = if let Some(ref rp) = real_old_path_owned {
|
||||||
.unwrap_or(old_path);
|
rp.as_c_str().as_ptr()
|
||||||
let real_new_path = get_cstr_path(ctx, new_path)
|
} else {
|
||||||
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
|
old_path
|
||||||
.unwrap_or(new_path);
|
};
|
||||||
|
let real_new_path_owned = get_cstr_path(ctx, new_path);
|
||||||
|
let real_new_path = if let Some(ref rp) = real_new_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
new_path
|
||||||
|
};
|
||||||
let result = unsafe { rename(real_old_path, real_new_path) };
|
let result = unsafe { rename(real_old_path, real_new_path) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> old_path: {}, new_path: {}, result: {}",
|
"=> old_path: {}, new_path: {}, result: {}",
|
||||||
@ -149,9 +158,12 @@ pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
|
|||||||
pub fn ___syscall40(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall40(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall40 (rmdir)");
|
debug!("emscripten::___syscall40 (rmdir)");
|
||||||
let pathname_addr = varargs.get_str(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
let real_path = get_cstr_path(ctx, pathname_addr)
|
let real_path_owned = get_cstr_path(ctx, pathname_addr);
|
||||||
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
.unwrap_or(pathname_addr);
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
unsafe { rmdir(real_path) }
|
unsafe { rmdir(real_path) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,16 +445,19 @@ pub fn ___syscall195(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
let pathname_addr = varargs.get_str(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
let buf: u32 = varargs.get(ctx);
|
let buf: u32 = varargs.get(ctx);
|
||||||
|
|
||||||
let real_path = get_cstr_path(ctx, pathname_addr)
|
let real_path_owned = get_cstr_path(ctx, pathname_addr);
|
||||||
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
.unwrap_or(pathname_addr);
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut _stat: stat = std::mem::zeroed();
|
let mut _stat: stat = std::mem::zeroed();
|
||||||
let ret = stat(real_path, &mut _stat);
|
let ret = stat(real_path, &mut _stat);
|
||||||
debug!(
|
debug!(
|
||||||
"=> pathname: {}, buf: {} = {}, last os error: {}",
|
"=> pathname: {}, buf: {} = {}, last os error: {}",
|
||||||
std::ffi::CStr::from_ptr(pathname_addr).to_str().unwrap(),
|
std::ffi::CStr::from_ptr(real_path).to_str().unwrap(),
|
||||||
buf,
|
buf,
|
||||||
ret,
|
ret,
|
||||||
Error::last_os_error()
|
Error::last_os_error()
|
||||||
|
@ -108,9 +108,12 @@ pub fn ___syscall5(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
|
|||||||
let pathname_addr = varargs.get_str(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
let flags: i32 = varargs.get(ctx);
|
let flags: i32 = varargs.get(ctx);
|
||||||
let mode: u32 = varargs.get(ctx);
|
let mode: u32 = varargs.get(ctx);
|
||||||
let real_path = utils::get_cstr_path(ctx, pathname_addr)
|
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
|
||||||
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
.unwrap_or(pathname_addr);
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
let _path_str = unsafe { std::ffi::CStr::from_ptr(real_path).to_str().unwrap() };
|
let _path_str = unsafe { std::ffi::CStr::from_ptr(real_path).to_str().unwrap() };
|
||||||
let fd = unsafe { open(real_path, flags, mode) };
|
let fd = unsafe { open(real_path, flags, mode) };
|
||||||
debug!(
|
debug!(
|
||||||
@ -158,12 +161,18 @@ pub fn ___syscall83(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
|
|||||||
|
|
||||||
let path1 = varargs.get_str(ctx);
|
let path1 = varargs.get_str(ctx);
|
||||||
let path2 = varargs.get_str(ctx);
|
let path2 = varargs.get_str(ctx);
|
||||||
let real_path1 = utils::get_cstr_path(ctx, path1)
|
let real_path1_owned = utils::get_cstr_path(ctx, path1);
|
||||||
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
|
let real_path1 = if let Some(ref rp) = real_path1_owned {
|
||||||
.unwrap_or(path1);
|
rp.as_c_str().as_ptr()
|
||||||
let real_path2 = utils::get_cstr_path(ctx, path2)
|
} else {
|
||||||
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
|
path1
|
||||||
.unwrap_or(path2);
|
};
|
||||||
|
let real_path2_owned = utils::get_cstr_path(ctx, path2);
|
||||||
|
let real_path2 = if let Some(ref rp) = real_path2_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
path2
|
||||||
|
};
|
||||||
let result = unsafe { symlink(real_path1, real_path2) };
|
let result = unsafe { symlink(real_path1, real_path2) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> path1: {}, path2: {}, result: {}",
|
"=> path1: {}, path2: {}, result: {}",
|
||||||
@ -191,12 +200,18 @@ pub fn ___syscall194(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
pub fn ___syscall198(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall198(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall198 (lchown) {}", _which);
|
debug!("emscripten::___syscall198 (lchown) {}", _which);
|
||||||
let path_ptr = varargs.get_str(ctx);
|
let path_ptr = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = utils::get_cstr_path(ctx, path_ptr);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
path_ptr
|
||||||
|
};
|
||||||
let uid: uid_t = varargs.get(ctx);
|
let uid: uid_t = varargs.get(ctx);
|
||||||
let gid: gid_t = varargs.get(ctx);
|
let gid: gid_t = varargs.get(ctx);
|
||||||
let result = unsafe { lchown(path_ptr, uid, gid) };
|
let result = unsafe { lchown(real_path, uid, gid) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> path: {}, uid: {}, gid: {}, result: {}",
|
"=> path: {}, uid: {}, gid: {}, result: {}",
|
||||||
unsafe { std::ffi::CStr::from_ptr(path_ptr).to_str().unwrap() },
|
unsafe { std::ffi::CStr::from_ptr(real_path).to_str().unwrap() },
|
||||||
uid,
|
uid,
|
||||||
gid,
|
gid,
|
||||||
result,
|
result,
|
||||||
@ -226,10 +241,16 @@ pub fn ___syscall212(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
debug!("emscripten::___syscall212 (chown) {}", _which);
|
debug!("emscripten::___syscall212 (chown) {}", _which);
|
||||||
|
|
||||||
let pathname_addr = varargs.get_str(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
let owner: u32 = varargs.get(ctx);
|
let owner: u32 = varargs.get(ctx);
|
||||||
let group: u32 = varargs.get(ctx);
|
let group: u32 = varargs.get(ctx);
|
||||||
|
|
||||||
unsafe { chown(pathname_addr, owner, group) }
|
unsafe { chown(real_path, owner, group) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// madvise
|
/// madvise
|
||||||
@ -249,11 +270,17 @@ pub fn ___syscall219(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
pub fn ___syscall33(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall33(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall33 (access) {}", _which);
|
debug!("emscripten::___syscall33 (access) {}", _which);
|
||||||
let path = varargs.get_str(ctx);
|
let path = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = utils::get_cstr_path(ctx, path);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
path
|
||||||
|
};
|
||||||
let amode: c_int = varargs.get(ctx);
|
let amode: c_int = varargs.get(ctx);
|
||||||
let result = unsafe { access(path, amode) };
|
let result = unsafe { access(real_path, amode) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> path: {}, amode: {}, result: {}",
|
"=> path: {}, amode: {}, result: {}",
|
||||||
unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() },
|
unsafe { std::ffi::CStr::from_ptr(real_path).to_str().unwrap() },
|
||||||
amode,
|
amode,
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
@ -271,8 +298,14 @@ pub fn ___syscall34(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
|
|||||||
pub fn ___syscall39(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall39(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall39 (mkdir) {}", _which);
|
debug!("emscripten::___syscall39 (mkdir) {}", _which);
|
||||||
let pathname_addr = varargs.get_str(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
let mode: u32 = varargs.get(ctx);
|
let mode: u32 = varargs.get(ctx);
|
||||||
unsafe { mkdir(pathname_addr, mode as _) }
|
unsafe { mkdir(real_path, mode as _) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// dup
|
/// dup
|
||||||
@ -771,6 +804,12 @@ pub fn ___syscall122(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
pub fn ___syscall196(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
|
pub fn ___syscall196(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
|
||||||
debug!("emscripten::___syscall196 (lstat64) {}", _which);
|
debug!("emscripten::___syscall196 (lstat64) {}", _which);
|
||||||
let path = varargs.get_str(ctx);
|
let path = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = utils::get_cstr_path(ctx, path);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
path
|
||||||
|
};
|
||||||
let buf_ptr: u32 = varargs.get(ctx);
|
let buf_ptr: u32 = varargs.get(ctx);
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut stat: stat = std::mem::zeroed();
|
let mut stat: stat = std::mem::zeroed();
|
||||||
@ -781,9 +820,9 @@ pub fn ___syscall196(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
|
|||||||
let stat_ptr = &mut stat as *mut stat;
|
let stat_ptr = &mut stat as *mut stat;
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
let ret = lstat64(path, stat_ptr);
|
let ret = lstat64(real_path, stat_ptr);
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
let ret = lstat(path, stat_ptr);
|
let ret = lstat(real_path, stat_ptr);
|
||||||
|
|
||||||
debug!("ret: {}", ret);
|
debug!("ret: {}", ret);
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::utils::copy_cstr_into_wasm;
|
use crate::utils::{copy_cstr_into_wasm, get_cstr_path};
|
||||||
use crate::varargs::VarArgs;
|
use crate::varargs::VarArgs;
|
||||||
use libc::mkdir;
|
use libc::mkdir;
|
||||||
use libc::open;
|
use libc::open;
|
||||||
@ -19,9 +19,15 @@ pub fn ___syscall5(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int {
|
|||||||
#[cfg(not(feature = "debug"))]
|
#[cfg(not(feature = "debug"))]
|
||||||
let _ = which;
|
let _ = which;
|
||||||
let pathname_addr = varargs.get_str(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = get_cstr_path(ctx, pathname_addr);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
let flags: i32 = varargs.get(ctx);
|
let flags: i32 = varargs.get(ctx);
|
||||||
let mode: u32 = varargs.get(ctx);
|
let mode: u32 = varargs.get(ctx);
|
||||||
let path_str = unsafe { std::ffi::CStr::from_ptr(pathname_addr).to_str().unwrap() };
|
let path_str = unsafe { std::ffi::CStr::from_ptr(real_path).to_str().unwrap() };
|
||||||
match path_str {
|
match path_str {
|
||||||
"/dev/urandom" => {
|
"/dev/urandom" => {
|
||||||
// create a fake urandom file for windows, super hacky
|
// create a fake urandom file for windows, super hacky
|
||||||
@ -47,7 +53,7 @@ pub fn ___syscall5(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int {
|
|||||||
fd
|
fd
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let fd = unsafe { open(pathname_addr, flags, mode) };
|
let fd = unsafe { open(real_path, flags, mode) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> pathname: {}, flags: {}, mode: {} = fd: {}\npath: {}",
|
"=> pathname: {}, flags: {}, mode: {} = fd: {}\npath: {}",
|
||||||
path_str, flags, mode, fd, path_str
|
path_str, flags, mode, fd, path_str
|
||||||
@ -95,7 +101,13 @@ pub fn ___syscall39(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int
|
|||||||
#[cfg(not(feature = "debug"))]
|
#[cfg(not(feature = "debug"))]
|
||||||
let _ = which;
|
let _ = which;
|
||||||
let pathname_addr = varargs.get_str(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
unsafe { mkdir(pathname_addr) }
|
let real_path_owned = get_cstr_path(ctx, pathname_addr);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
|
unsafe { mkdir(real_path) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// dup
|
/// dup
|
||||||
|
@ -208,12 +208,36 @@ pub fn read_string_from_wasm(memory: &Memory, offset: u32) -> String {
|
|||||||
/// This function trys to find an entry in mapdir
|
/// This function trys to find an entry in mapdir
|
||||||
/// translating paths into their correct value
|
/// translating paths into their correct value
|
||||||
pub fn get_cstr_path(ctx: &mut Ctx, path: *const i8) -> Option<std::ffi::CString> {
|
pub fn get_cstr_path(ctx: &mut Ctx, path: *const i8) -> Option<std::ffi::CString> {
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
let path_str = unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() }.to_string();
|
let path_str = unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() }.to_string();
|
||||||
if let Some(val) = get_emscripten_data(ctx).mapped_dirs.get(&path_str) {
|
let data = get_emscripten_data(ctx);
|
||||||
std::ffi::CString::new(val.to_string_lossy().as_bytes()).ok()
|
let path = PathBuf::from(path_str);
|
||||||
} else {
|
let mut prefix_added = false;
|
||||||
None
|
let mut components = path.components().collect::<VecDeque<_>>();
|
||||||
|
// TODO(mark): handle absolute/non-canonical/non-relative paths too (this
|
||||||
|
// functionality should be shared among the abis)
|
||||||
|
if components.len() == 1 {
|
||||||
|
components.push_front(std::path::Component::CurDir);
|
||||||
|
prefix_added = true;
|
||||||
}
|
}
|
||||||
|
let mut cumulative_path = PathBuf::new();
|
||||||
|
for c in components.into_iter() {
|
||||||
|
cumulative_path.push(c);
|
||||||
|
if let Some(val) = data
|
||||||
|
.mapped_dirs
|
||||||
|
.get(&cumulative_path.to_string_lossy().to_string())
|
||||||
|
{
|
||||||
|
let rest_of_path = if !prefix_added {
|
||||||
|
path.strip_prefix(cumulative_path).ok()?
|
||||||
|
} else {
|
||||||
|
&path
|
||||||
|
};
|
||||||
|
let rebased_path = val.join(rest_of_path);
|
||||||
|
return std::ffi::CString::new(rebased_path.to_string_lossy().as_bytes()).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// gets the current directory
|
/// gets the current directory
|
||||||
|
@ -445,9 +445,6 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
|||||||
.instantiate(&import_object)
|
.instantiate(&import_object)
|
||||||
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
||||||
|
|
||||||
if !mapped_dirs.is_empty() {
|
|
||||||
eprintln!("WARN: mapdir is not implemented for emscripten targets");
|
|
||||||
}
|
|
||||||
wasmer_emscripten::run_emscripten_instance(
|
wasmer_emscripten::run_emscripten_instance(
|
||||||
&module,
|
&module,
|
||||||
&mut instance,
|
&mut instance,
|
||||||
|
Reference in New Issue
Block a user