]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/sgx/args.rs
`#[deny(unsafe_op_in_unsafe_fn)]` in sys/sgx
[rust.git] / library / std / src / sys / sgx / args.rs
1 use super::abi::usercalls::{alloc, raw::ByteBuffer};
2 use crate::ffi::OsString;
3 use crate::slice;
4 use crate::sync::atomic::{AtomicUsize, Ordering};
5 use crate::sys::os_str::Buf;
6 use crate::sys_common::FromInner;
7
8 #[cfg_attr(test, linkage = "available_externally")]
9 #[export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE"]
10 static ARGS: AtomicUsize = AtomicUsize::new(0);
11 type ArgsStore = Vec<OsString>;
12
13 #[cfg_attr(test, allow(dead_code))]
14 pub unsafe fn init(argc: isize, argv: *const *const u8) {
15     if argc != 0 {
16         let args = unsafe { alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _) };
17         let args = args
18             .iter()
19             .map(|a| OsString::from_inner(Buf { inner: a.copy_user_buffer() }))
20             .collect::<ArgsStore>();
21         ARGS.store(Box::into_raw(Box::new(args)) as _, Ordering::Relaxed);
22     }
23 }
24
25 pub unsafe fn cleanup() {}
26
27 pub fn args() -> Args {
28     let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
29     if let Some(args) = args { Args(args.iter()) } else { Args([].iter()) }
30 }
31
32 pub struct Args(slice::Iter<'static, OsString>);
33
34 impl Args {
35     pub fn inner_debug(&self) -> &[OsString] {
36         self.0.as_slice()
37     }
38 }
39
40 impl Iterator for Args {
41     type Item = OsString;
42     fn next(&mut self) -> Option<OsString> {
43         self.0.next().cloned()
44     }
45     fn size_hint(&self) -> (usize, Option<usize>) {
46         self.0.size_hint()
47     }
48 }
49
50 impl ExactSizeIterator for Args {
51     fn len(&self) -> usize {
52         self.0.len()
53     }
54 }
55
56 impl DoubleEndedIterator for Args {
57     fn next_back(&mut self) -> Option<OsString> {
58         self.0.next_back().cloned()
59     }
60 }