]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/hermit/args.rs
Rollup merge of #105362 - WaffleLapkin:🙅, r=oli-obk
[rust.git] / library / std / src / sys / hermit / args.rs
1 use crate::ffi::{c_char, CStr, OsString};
2 use crate::fmt;
3 use crate::os::unix::ffi::OsStringExt;
4 use crate::ptr;
5 use crate::sync::atomic::{
6     AtomicIsize, AtomicPtr,
7     Ordering::{Acquire, Relaxed, Release},
8 };
9 use crate::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.
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
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)
28         .map(|i| unsafe {
29             let cstr = CStr::from_ptr(*argv.offset(i) as *const c_char);
30             OsStringExt::from_vec(cstr.to_bytes().to_vec())
31         })
32         .collect();
33
34     Args { iter: args.into_iter() }
35 }
36
37 pub struct Args {
38     iter: vec::IntoIter<OsString>,
39 }
40
41 impl fmt::Debug for Args {
42     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43         self.iter.as_slice().fmt(f)
44     }
45 }
46
47 impl !Send for Args {}
48 impl !Sync for Args {}
49
50 impl Iterator for Args {
51     type Item = OsString;
52     fn next(&mut self) -> Option<OsString> {
53         self.iter.next()
54     }
55     fn size_hint(&self) -> (usize, Option<usize>) {
56         self.iter.size_hint()
57     }
58 }
59
60 impl ExactSizeIterator for Args {
61     fn len(&self) -> usize {
62         self.iter.len()
63     }
64 }
65
66 impl DoubleEndedIterator for Args {
67     fn next_back(&mut self) -> Option<OsString> {
68         self.iter.next_back()
69     }
70 }