mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-16 16:20:49 +00:00
Merge pull request #52 from wasmerio/fix/emscripten-env
Fix support for env vars (put, set, unset)
This commit is contained in:
commit
db24e8ae69
@ -11,7 +11,7 @@ use std::process::Command;
|
||||
static BANNER: &str = "// Rust test file autogenerated with cargo build (build/emtests.rs).
|
||||
// Please do NOT modify it by hand, as it will be reseted on next build.\n";
|
||||
|
||||
const TESTS: [&str; 2] = ["emtests/puts.c", "emtests/printf.c"];
|
||||
const TESTS: [&str; 3] = ["emtests/env.c", "emtests/puts.c", "emtests/printf.c"];
|
||||
|
||||
pub fn compile(file: &str) -> String {
|
||||
let mut output_path = PathBuf::from(file);
|
||||
|
25
emtests/env.c
Normal file
25
emtests/env.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
int main()
|
||||
{
|
||||
printf("INIT\n");
|
||||
const char* UNEXISTENT_ENVVAR = getenv("UNEXISTENT_ENVVAR");
|
||||
printf("UNEXISTENT_ENVVAR = %s\n",(UNEXISTENT_ENVVAR!=NULL)? UNEXISTENT_ENVVAR : "[NULL]");
|
||||
printf("Setting UNEXISTENT_ENVVAR=PUTENV (via putenv)\n");
|
||||
putenv("UNEXISTENT_ENVVAR=PUTENV");
|
||||
UNEXISTENT_ENVVAR = getenv("UNEXISTENT_ENVVAR");
|
||||
printf("UNEXISTENT_ENVVAR = %s\n",(UNEXISTENT_ENVVAR!=NULL)? UNEXISTENT_ENVVAR : "[NULL]");
|
||||
printf("Setting UNEXISTENT_ENVVAR=SETENV (via setenv, overwrite)\n");
|
||||
setenv("UNEXISTENT_ENVVAR", "SETENV", 1);
|
||||
UNEXISTENT_ENVVAR = getenv("UNEXISTENT_ENVVAR");
|
||||
printf("UNEXISTENT_ENVVAR = %s\n",(UNEXISTENT_ENVVAR!=NULL)? UNEXISTENT_ENVVAR : "[NULL]");
|
||||
printf("Setting UNEXISTENT_ENVVAR=SETENV_NEW (via setenv, NO overwrite)\n");
|
||||
setenv("UNEXISTENT_ENVVAR", "SETENV_NEW", 0);
|
||||
UNEXISTENT_ENVVAR = getenv("UNEXISTENT_ENVVAR");
|
||||
printf("UNEXISTENT_ENVVAR = %s\n",(UNEXISTENT_ENVVAR!=NULL)? UNEXISTENT_ENVVAR : "[NULL]");
|
||||
printf("Unsetting UNEXISTENT_ENVVAR\n");
|
||||
unsetenv("UNEXISTENT_ENVVAR");
|
||||
UNEXISTENT_ENVVAR = getenv("UNEXISTENT_ENVVAR");
|
||||
printf("UNEXISTENT_ENVVAR = %s\n",(UNEXISTENT_ENVVAR!=NULL)? UNEXISTENT_ENVVAR : "[NULL]");
|
||||
printf("END\n");
|
||||
}
|
11
emtests/env.output
Normal file
11
emtests/env.output
Normal file
@ -0,0 +1,11 @@
|
||||
INIT
|
||||
UNEXISTENT_ENVVAR = [NULL]
|
||||
Setting UNEXISTENT_ENVVAR=PUTENV (via putenv)
|
||||
UNEXISTENT_ENVVAR = PUTENV
|
||||
Setting UNEXISTENT_ENVVAR=SETENV (via setenv, overwrite)
|
||||
UNEXISTENT_ENVVAR = SETENV
|
||||
Setting UNEXISTENT_ENVVAR=SETENV_NEW (via setenv, NO overwrite)
|
||||
UNEXISTENT_ENVVAR = SETENV
|
||||
Unsetting UNEXISTENT_ENVVAR
|
||||
UNEXISTENT_ENVVAR = [NULL]
|
||||
END
|
BIN
emtests/env.wasm
Normal file
BIN
emtests/env.wasm
Normal file
Binary file not shown.
Binary file not shown.
@ -26,9 +26,21 @@
|
||||
|
||||
###### ENVIRONMENT
|
||||
|
||||
- **\_getenv** [:top:](#host-apis)
|
||||
- **\_getenv** ✅ [:top:](#host-apis)
|
||||
```rust
|
||||
|
||||
fn _getenv(name: c_int, instance: &mut Instance)
|
||||
```
|
||||
- **\_putenv** ✅ [:top:](#host-apis)
|
||||
```rust
|
||||
fn _putenv(name: c_int, instance: &mut Instance)
|
||||
```
|
||||
- **\_setenv** ✅ [:top:](#host-apis)
|
||||
```rust
|
||||
fn _setenv(name: c_int, value: c_int, overwrite: c_int, instance: &mut Instance
|
||||
```
|
||||
- **\_unsetenv** ✅ [:top:](#host-apis)
|
||||
```rust
|
||||
fn _unsetenv(name: c_int, instance: &mut Instance)
|
||||
```
|
||||
|
||||
###### THREAD
|
||||
@ -44,10 +56,6 @@
|
||||
- **\_pthread_setspecific** [:top:](#host-apis)
|
||||
```rust
|
||||
|
||||
```
|
||||
- **\_unsetenv** [:top:](#host-apis)
|
||||
```rust
|
||||
|
||||
```
|
||||
- **\_\_\_lock** [:top:](#host-apis)
|
||||
```rust
|
||||
|
@ -1,11 +1,14 @@
|
||||
use super::super::host;
|
||||
/// NOTE: These syscalls only support wasm_32 for now because they take u32 offset
|
||||
use libc::{c_int, c_long, getenv, getgrnam as libc_getgrnam, getpwnam as libc_getpwnam, sysconf};
|
||||
use libc::{
|
||||
c_int, c_long, getenv, getgrnam as libc_getgrnam, getpwnam as libc_getpwnam, putenv, setenv,
|
||||
sysconf, unsetenv,
|
||||
};
|
||||
use std::ffi::CStr;
|
||||
use std::mem;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
use super::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
|
||||
use super::utils::{allocate_on_stack, copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
|
||||
use crate::webassembly::Instance;
|
||||
|
||||
// #[no_mangle]
|
||||
@ -25,6 +28,41 @@ pub extern "C" fn _getenv(name: c_int, instance: &mut Instance) -> u32 {
|
||||
unsafe { copy_cstr_into_wasm(instance, c_str) }
|
||||
}
|
||||
|
||||
/// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int);
|
||||
pub extern "C" fn _setenv(name: c_int, value: c_int, overwrite: c_int, instance: &mut Instance) {
|
||||
debug!("emscripten::_setenv");
|
||||
|
||||
let name_addr = instance.memory_offset_addr(0, name as usize) as *const c_char;
|
||||
let value_addr = instance.memory_offset_addr(0, value as usize) as *const c_char;
|
||||
|
||||
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
||||
debug!("=> value({:?})", unsafe { CStr::from_ptr(value_addr) });
|
||||
|
||||
unsafe { setenv(name_addr, value_addr, overwrite) };
|
||||
}
|
||||
|
||||
/// emscripten: _putenv // (name: *const char);
|
||||
pub extern "C" fn _putenv(name: c_int, instance: &mut Instance) {
|
||||
debug!("emscripten::_putenv");
|
||||
|
||||
let name_addr = instance.memory_offset_addr(0, name as usize) as *const c_char;
|
||||
|
||||
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
||||
|
||||
unsafe { putenv(name_addr as _) };
|
||||
}
|
||||
|
||||
/// emscripten: _unsetenv // (name: *const char);
|
||||
pub extern "C" fn _unsetenv(name: c_int, instance: &mut Instance) {
|
||||
debug!("emscripten::_unsetenv");
|
||||
|
||||
let name_addr = instance.memory_offset_addr(0, name as usize) as *const c_char;
|
||||
|
||||
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
||||
|
||||
unsafe { unsetenv(name_addr) };
|
||||
}
|
||||
|
||||
pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
|
||||
debug!("emscripten::_getpwnam {}", name_ptr);
|
||||
|
||||
@ -104,8 +142,26 @@ pub extern "C" fn _getpagesize() -> u32 {
|
||||
16384
|
||||
}
|
||||
|
||||
pub extern "C" fn ___build_environment(environ: c_int) {
|
||||
pub extern "C" fn ___build_environment(environ: c_int, instance: &mut Instance) {
|
||||
debug!("emscripten::___build_environment {}", environ);
|
||||
const MAX_ENV_VALUES: u32 = 64;
|
||||
const TOTAL_ENV_SIZE: u32 = 1024;
|
||||
let mut environment = instance.memory_offset_addr(0, environ as _) as *mut c_int;
|
||||
unsafe {
|
||||
let (pool_offset, pool_slice): (u32, &mut [u8]) =
|
||||
allocate_on_stack(TOTAL_ENV_SIZE as u32, instance);
|
||||
let (env_offset, env_slice): (u32, &mut [u8]) =
|
||||
allocate_on_stack((MAX_ENV_VALUES * 4) as u32, instance);
|
||||
let mut env_ptr = instance.memory_offset_addr(0, env_offset as _) as *mut c_int;
|
||||
let mut pool_ptr = instance.memory_offset_addr(0, pool_offset as _) as *mut c_int;
|
||||
*env_ptr = pool_offset as i32;
|
||||
*environment = env_offset as i32;
|
||||
|
||||
// *env_ptr = 0;
|
||||
};
|
||||
// unsafe {
|
||||
// *env_ptr = 0;
|
||||
// };
|
||||
}
|
||||
|
||||
pub extern "C" fn _sysconf(name: c_int, _instance: &mut Instance) -> c_long {
|
||||
|
@ -114,6 +114,9 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
import_object.set("env", "___wait", ImportValue::Func(lock::___wait as _));
|
||||
// Env
|
||||
import_object.set("env", "_getenv", ImportValue::Func(env::_getenv as _));
|
||||
import_object.set("env", "_setenv", ImportValue::Func(env::_setenv as _));
|
||||
import_object.set("env", "_putenv", ImportValue::Func(env::_putenv as _));
|
||||
import_object.set("env", "_unsetenv", ImportValue::Func(env::_unsetenv as _));
|
||||
import_object.set("env", "_getpwnam", ImportValue::Func(env::_getpwnam as _));
|
||||
import_object.set("env", "_getgrnam", ImportValue::Func(env::_getgrnam as _));
|
||||
import_object.set(
|
||||
|
9
src/emtests/env.rs
Normal file
9
src/emtests/env.rs
Normal file
@ -0,0 +1,9 @@
|
||||
#[test]
|
||||
fn test_env() {
|
||||
assert_emscripten_output!(
|
||||
"../../emtests/env.wasm",
|
||||
"env",
|
||||
vec![],
|
||||
"../../emtests/env.output"
|
||||
);
|
||||
}
|
@ -4,5 +4,6 @@
|
||||
// The _common module is not autogenerated, as it provides common macros for the emtests
|
||||
#[macro_use]
|
||||
mod _common;
|
||||
mod env;
|
||||
mod printf;
|
||||
mod puts;
|
||||
|
Loading…
x
Reference in New Issue
Block a user