Skip to content

Commit

Permalink
wasi: Load arguments via syscalls
Browse files Browse the repository at this point in the history
This commit switches the wasi target to loading CLI arguments via the
syscalls provided by wasi rather than through the argc/argv passed to
the main function. While serving the same purpose it's hoped that using
syscalls will make us a bit more portable (less reliance from libstd on
an external C library) as well as avoiding the need for a lock!
  • Loading branch information
alexcrichton committed Apr 1, 2019
1 parent eab3eb3 commit 382f9a7
Showing 1 changed file with 24 additions and 26 deletions.
50 changes: 24 additions & 26 deletions src/libstd/sys/wasi/args.rs
@@ -1,30 +1,15 @@
use crate::any::Any;
use crate::ffi::CStr;
use crate::io;
use crate::sys::cvt_wasi;
use crate::ffi::OsString;
use crate::marker::PhantomData;
use crate::os::wasi::ffi::OsStringExt;
use crate::ptr;
use crate::vec;

static mut ARGC: isize = 0;
static mut ARGV: *const *const u8 = ptr::null();

#[cfg(not(target_feature = "atomics"))]
pub unsafe fn args_lock() -> impl Any {
// No need for a lock if we're single-threaded, but this function will need
// to get implemented for multi-threaded scenarios
}

pub unsafe fn init(argc: isize, argv: *const *const u8) {
let _guard = args_lock();
ARGC = argc;
ARGV = argv;
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
}

pub unsafe fn cleanup() {
let _guard = args_lock();
ARGC = 0;
ARGV = ptr::null();
}

pub struct Args {
Expand All @@ -34,18 +19,31 @@ pub struct Args {

/// Returns the command line arguments
pub fn args() -> Args {
maybe_args().unwrap_or_else(|_| {
Args {
iter: Vec::new().into_iter(),
_dont_send_or_sync_me: PhantomData
}
})
}

fn maybe_args() -> io::Result<Args> {
unsafe {
let _guard = args_lock();
let args = (0..ARGC)
.map(|i| {
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
OsStringExt::from_vec(cstr.to_bytes().to_vec())
})
let (mut argc, mut argv_buf_size) = (0, 0);
cvt_wasi(libc::__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?;

let mut argc = vec![0 as *mut libc::c_char; argc];
let mut argv_buf = vec![0; argv_buf_size];
cvt_wasi(libc::__wasi_args_get(argc.as_mut_ptr(), argv_buf.as_mut_ptr()))?;

let args = argc.into_iter()
.map(|ptr| CStr::from_ptr(ptr).to_bytes().to_vec())
.map(|bytes| OsString::from_vec(bytes))
.collect::<Vec<_>>();
Args {
Ok(Args {
iter: args.into_iter(),
_dont_send_or_sync_me: PhantomData,
}
})
}
}

Expand Down

0 comments on commit 382f9a7

Please sign in to comment.