1 use crate::ffi::{c_char, CStr, OsString};
3 use crate::os::unix::ffi::OsStringExt;
5 use crate::sync::atomic::{
6 AtomicIsize, AtomicPtr,
7 Ordering::{Acquire, Relaxed, Release},
11 static ARGC: AtomicIsize = AtomicIsize::new(0);
12 static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
14 /// One-time global initialization.
15 pub unsafe fn init(argc: isize, argv: *const *const u8) {
16 ARGC.store(argc, Relaxed);
17 // Use release ordering here to broadcast writes by the OS.
18 ARGV.store(argv as *mut *const u8, Release);
21 /// Returns the command line arguments
22 pub fn args() -> Args {
23 // Synchronize with the store above.
24 let argv = ARGV.load(Acquire);
25 // If argv has not been initialized yet, do not return any arguments.
26 let argc = if argv.is_null() { 0 } else { ARGC.load(Relaxed) };
27 let args: Vec<OsString> = (0..argc)
29 let cstr = CStr::from_ptr(*argv.offset(i) as *const c_char);
30 OsStringExt::from_vec(cstr.to_bytes().to_vec())
34 Args { iter: args.into_iter() }
38 iter: vec::IntoIter<OsString>,
41 impl fmt::Debug for Args {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 self.iter.as_slice().fmt(f)
47 impl !Send for Args {}
48 impl !Sync for Args {}
50 impl Iterator for Args {
52 fn next(&mut self) -> Option<OsString> {
55 fn size_hint(&self) -> (usize, Option<usize>) {
60 impl ExactSizeIterator for Args {
61 fn len(&self) -> usize {
66 impl DoubleEndedIterator for Args {
67 fn next_back(&mut self) -> Option<OsString> {