diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2019-03-31 14:39:03 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2019-04-01 05:29:53 -0700 |
| commit | 382f9a7a3d15580c15531428f39bf47f55093d42 (patch) | |
| tree | 2f070019f6203c4bf2fc024608a27dc24e224768 /src/libstd/sys/wasi | |
| parent | eab3eb38df8dca99110b6149b3a15deeb4ef0413 (diff) | |
| download | rust-382f9a7a3d15580c15531428f39bf47f55093d42.tar.gz rust-382f9a7a3d15580c15531428f39bf47f55093d42.zip | |
wasi: Load arguments via syscalls
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!
Diffstat (limited to 'src/libstd/sys/wasi')
| -rw-r--r-- | src/libstd/sys/wasi/args.rs | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 20558a8042d..9c8e59e4fb5 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/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 { @@ -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, - } + }) } } |
