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::vec; pub unsafe fn init(_argc: isize, _argv: *const *const u8) { } pub unsafe fn cleanup() { } pub struct Args { iter: vec::IntoIter, _dont_send_or_sync_me: PhantomData<*mut ()>, } /// 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 { unsafe { 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![core::ptr::null_mut::(); 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::>(); Ok(Args { iter: args.into_iter(), _dont_send_or_sync_me: PhantomData, }) } } impl Args { pub fn inner_debug(&self) -> &[OsString] { self.iter.as_slice() } } impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl ExactSizeIterator for Args { fn len(&self) -> usize { self.iter.len() } } impl DoubleEndedIterator for Args { fn next_back(&mut self) -> Option { self.iter.next_back() } }