1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
use crate::ffi::{c_char, CStr, OsString};
use crate::fmt;
use crate::os::hermit::ffi::OsStringExt;
use crate::ptr;
use crate::sync::atomic::{
AtomicIsize, AtomicPtr,
Ordering::{Acquire, Relaxed, Release},
};
use crate::vec;
static ARGC: AtomicIsize = AtomicIsize::new(0);
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
/// One-time global initialization.
pub unsafe fn init(argc: isize, argv: *const *const u8) {
ARGC.store(argc, Relaxed);
// Use release ordering here to broadcast writes by the OS.
ARGV.store(argv as *mut *const u8, Release);
}
/// Returns the command line arguments
pub fn args() -> Args {
// Synchronize with the store above.
let argv = ARGV.load(Acquire);
// If argv has not been initialized yet, do not return any arguments.
let argc = if argv.is_null() { 0 } else { ARGC.load(Relaxed) };
let args: Vec<OsString> = (0..argc)
.map(|i| unsafe {
let cstr = CStr::from_ptr(*argv.offset(i) as *const c_char);
OsStringExt::from_vec(cstr.to_bytes().to_vec())
})
.collect();
Args { iter: args.into_iter() }
}
pub struct Args {
iter: vec::IntoIter<OsString>,
}
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.iter.as_slice().fmt(f)
}
}
impl !Send for Args {}
impl !Sync for Args {}
impl Iterator for Args {
type Item = OsString;
fn next(&mut self) -> Option<OsString> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
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<OsString> {
self.iter.next_back()
}
}
|