xref: /drstd/src/std/sys/hermit/args.rs (revision 9670759b785600bf6315e4173e46a602f16add7a)
1 use crate::std::ffi::{c_char, CStr, OsString};
2 use crate::std::fmt;
3 use crate::std::os::hermit::ffi::OsStringExt;
4 use crate::std::ptr;
5 use crate::std::sync::atomic::{
6     AtomicIsize, AtomicPtr,
7     Ordering::{Acquire, Relaxed, Release},
8 };
9 use crate::std::vec;
10 
11 static ARGC: AtomicIsize = AtomicIsize::new(0);
12 static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
13 
14 /// One-time global initialization.
init(argc: isize, argv: *const *const u8)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);
19 }
20 
21 /// Returns the command line arguments
args() -> Args22 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() {
27         0
28     } else {
29         ARGC.load(Relaxed)
30     };
31     let args: Vec<OsString> = (0..argc)
32         .map(|i| unsafe {
33             let cstr = CStr::from_ptr(*argv.offset(i) as *const c_char);
34             OsStringExt::from_vec(cstr.to_bytes().to_vec())
35         })
36         .collect();
37 
38     Args {
39         iter: args.into_iter(),
40     }
41 }
42 
43 pub struct Args {
44     iter: vec::IntoIter<OsString>,
45 }
46 
47 impl fmt::Debug for Args {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result48     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49         self.iter.as_slice().fmt(f)
50     }
51 }
52 
53 impl !Send for Args {}
54 impl !Sync for Args {}
55 
56 impl Iterator for Args {
57     type Item = OsString;
next(&mut self) -> Option<OsString>58     fn next(&mut self) -> Option<OsString> {
59         self.iter.next()
60     }
size_hint(&self) -> (usize, Option<usize>)61     fn size_hint(&self) -> (usize, Option<usize>) {
62         self.iter.size_hint()
63     }
64 }
65 
66 impl ExactSizeIterator for Args {
len(&self) -> usize67     fn len(&self) -> usize {
68         self.iter.len()
69     }
70 }
71 
72 impl DoubleEndedIterator for Args {
next_back(&mut self) -> Option<OsString>73     fn next_back(&mut self) -> Option<OsString> {
74         self.iter.next_back()
75     }
76 }
77