std: xous: add support for args and env · qinheping/verify-rust-std@3919c4f (original) (raw)
1
1
`use super::unsupported;
`
``
2
`+
use crate::collections::HashMap;
`
2
3
`use crate::error::Error as StdError;
`
3
4
`use crate::ffi::{OsStr, OsString};
`
4
5
`use crate:📑:PhantomData;
`
5
6
`use crate::os::xous::ffi::Error as XousError;
`
6
7
`use crate::path::{self, PathBuf};
`
7
``
`-
use crate::{fmt, io};
`
``
8
`+
use crate::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
`
``
9
`+
use crate::sync::{Mutex, Once};
`
``
10
`+
use crate::{fmt, io, vec};
`
``
11
+
``
12
`+
pub(crate) mod params;
`
``
13
+
``
14
`+
static PARAMS_ADDRESS: AtomicPtr = AtomicPtr::new(core::ptr::null_mut());
`
8
15
``
9
16
`#[cfg(not(test))]
`
10
17
`#[cfg(feature = "panic_unwind")]
`
11
18
`mod eh_unwinding {
`
12
``
`-
pub(crate) struct EhFrameFinder(usize /* eh_frame */);
`
13
``
`-
pub(crate) static mut EH_FRAME_SETTINGS: EhFrameFinder = EhFrameFinder(0);
`
14
``
`-
impl EhFrameFinder {
`
15
``
`-
pub(crate) unsafe fn init(&mut self, eh_frame: usize) {
`
16
``
`-
unsafe {
`
17
``
`-
EH_FRAME_SETTINGS.0 = eh_frame;
`
18
``
`-
}
`
19
``
`-
}
`
20
``
`-
}
`
``
19
`+
pub(crate) struct EhFrameFinder;
`
``
20
`+
pub(crate) static mut EH_FRAME_ADDRESS: usize = 0;
`
``
21
`+
pub(crate) static EH_FRAME_SETTINGS: EhFrameFinder = EhFrameFinder;
`
``
22
+
21
23
`unsafe impl unwind::EhFrameFinder for EhFrameFinder {
`
22
24
`fn find(&self, _pc: usize) -> Optionunwind::FrameInfo {
`
23
``
`-
Some(unwind::FrameInfo {
`
24
``
`-
text_base: None,
`
25
``
`-
kind: unwind::FrameInfoKind::EhFrame(self.0),
`
26
``
`-
})
`
``
25
`+
if unsafe { EH_FRAME_ADDRESS == 0 } {
`
``
26
`+
None
`
``
27
`+
} else {
`
``
28
`+
Some(unwind::FrameInfo {
`
``
29
`+
text_base: None,
`
``
30
`+
kind: unwind::FrameInfoKind::EhFrame(unsafe { EH_FRAME_ADDRESS }),
`
``
31
`+
})
`
``
32
`+
}
`
27
33
`}
`
28
34
`}
`
29
35
`}
`
`@@ -41,12 +47,21 @@ mod c_compat {
`
41
47
`}
`
42
48
``
43
49
`#[no_mangle]
`
44
``
`-
pub extern "C" fn _start(eh_frame: usize) {
`
``
50
`+
pub extern "C" fn _start(eh_frame: usize, params_address: usize) {
`
45
51
`#[cfg(feature = "panic_unwind")]
`
46
``
`-
unsafe {
`
47
``
`-
super::eh_unwinding::EH_FRAME_SETTINGS.init(eh_frame);
`
``
52
`+
{
`
``
53
`+
unsafe { super::eh_unwinding::EH_FRAME_ADDRESS = eh_frame };
`
48
54
` unwind::set_custom_eh_frame_finder(&super::eh_unwinding::EH_FRAME_SETTINGS).ok();
`
49
55
`}
`
``
56
+
``
57
`+
if params_address != 0 {
`
``
58
`+
let params_address = crate::ptr::with_exposed_provenance_mut::(params_address);
`
``
59
`+
if unsafe {
`
``
60
`+
super::params::ApplicationParameters::new_from_ptr(params_address).is_some()
`
``
61
`+
} {
`
``
62
`+
super::PARAMS_ADDRESS.store(params_address, core::sync::atomic::Ordering::Relaxed);
`
``
63
`+
}
`
``
64
`+
}
`
50
65
`exit(unsafe { main() });
`
51
66
`}
`
52
67
``
`@@ -116,44 +131,103 @@ pub fn current_exe() -> io::Result {
`
116
131
`unsupported()
`
117
132
`}
`
118
133
``
119
``
`-
pub struct Env(!);
`
``
134
`+
pub(crate) fn get_application_parameters() -> Optionparams::ApplicationParameters {
`
``
135
`+
let params_address = PARAMS_ADDRESS.load(Ordering::Relaxed);
`
``
136
`+
unsafe { params::ApplicationParameters::new_from_ptr(params_address) }
`
``
137
`+
}
`
``
138
+
``
139
`+
// ---------- Environment handling ---------- //
`
``
140
`+
static ENV: AtomicUsize = AtomicUsize::new(0);
`
``
141
`+
static ENV_INIT: Once = Once::new();
`
``
142
`+
type EnvStore = Mutex<HashMap<OsString, OsString>>;
`
``
143
+
``
144
`+
fn get_env_store() -> &'static EnvStore {
`
``
145
`+
ENV_INIT.call_once(|| {
`
``
146
`+
let env_store = EnvStore::default();
`
``
147
`+
if let Some(params) = get_application_parameters() {
`
``
148
`+
for param in params {
`
``
149
`+
if let Ok(envs) = params::EnvironmentBlock::try_from(¶m) {
`
``
150
`+
let mut env_store = env_store.lock().unwrap();
`
``
151
`+
for env in envs {
`
``
152
`+
env_store.insert(env.key.into(), env.value.into());
`
``
153
`+
}
`
``
154
`+
break;
`
``
155
`+
}
`
``
156
`+
}
`
``
157
`+
}
`
``
158
`+
ENV.store(Box::into_raw(Box::new(env_store)) as _, Ordering::Relaxed)
`
``
159
`+
});
`
``
160
`+
unsafe { &*core::ptr::with_exposed_provenance::(ENV.load(Ordering::Relaxed)) }
`
``
161
`+
}
`
``
162
+
``
163
`+
pub struct Env {
`
``
164
`+
iter: vec::IntoIter<(OsString, OsString)>,
`
``
165
`+
}
`
``
166
+
``
167
`+
// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when ::fmt matches ::fmt.
`
``
168
`+
pub struct EnvStrDebug<'a> {
`
``
169
`+
slice: &'a [(OsString, OsString)],
`
``
170
`+
}
`
``
171
+
``
172
`+
impl fmt::Debug for EnvStrDebug<'_> {
`
``
173
`+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
`
``
174
`+
let Self { slice } = self;
`
``
175
`+
f.debug_list()
`
``
176
`+
.entries(slice.iter().map(|(a, b)| (a.to_str().unwrap(), b.to_str().unwrap())))
`
``
177
`+
.finish()
`
``
178
`+
}
`
``
179
`+
}
`
120
180
``
121
181
`impl Env {
`
122
182
`// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when ::fmt matches ::fmt.
`
123
183
`pub fn str_debug(&self) -> impl fmt::Debug + '_ {
`
124
``
`-
let Self(inner) = self;
`
125
``
`-
match *inner {}
`
``
184
`+
let Self { iter } = self;
`
``
185
`+
EnvStrDebug { slice: iter.as_slice() }
`
126
186
`}
`
127
187
`}
`
128
188
``
129
189
`impl fmt::Debug for Env {
`
130
``
`-
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
`
131
``
`-
let Self(inner) = self;
`
132
``
`-
match *inner {}
`
``
190
`+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
`
``
191
`+
let Self { iter } = self;
`
``
192
`+
f.debug_list().entries(iter.as_slice()).finish()
`
133
193
`}
`
134
194
`}
`
135
195
``
``
196
`+
impl !Send for Env {}
`
``
197
`+
impl !Sync for Env {}
`
``
198
+
136
199
`impl Iterator for Env {
`
137
200
`type Item = (OsString, OsString);
`
138
201
`fn next(&mut self) -> Option<(OsString, OsString)> {
`
139
``
`-
self.0
`
``
202
`+
self.iter.next()
`
``
203
`+
}
`
``
204
`+
fn size_hint(&self) -> (usize, Option) {
`
``
205
`+
self.iter.size_hint()
`
140
206
`}
`
141
207
`}
`
142
208
``
143
209
`pub fn env() -> Env {
`
144
``
`-
panic!("not supported on this platform")
`
``
210
`+
let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> {
`
``
211
`+
map.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
`
``
212
`+
};
`
``
213
+
``
214
`+
let iter = clone_to_vec(&*get_env_store().lock().unwrap()).into_iter();
`
``
215
`+
Env { iter }
`
145
216
`}
`
146
217
``
147
``
`-
pub fn getenv(_: &OsStr) -> Option {
`
148
``
`-
None
`
``
218
`+
pub fn getenv(k: &OsStr) -> Option {
`
``
219
`+
get_env_store().lock().unwrap().get(k).cloned()
`
149
220
`}
`
150
221
``
151
``
`-
pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
`
152
``
`-
Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
`
``
222
`+
pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
`
``
223
`+
let (k, v) = (k.to_owned(), v.to_owned());
`
``
224
`+
get_env_store().lock().unwrap().insert(k, v);
`
``
225
`+
Ok(())
`
153
226
`}
`
154
227
``
155
``
`-
pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> {
`
156
``
`-
Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
`
``
228
`+
pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> {
`
``
229
`+
get_env_store().lock().unwrap().remove(k);
`
``
230
`+
Ok(())
`
157
231
`}
`
158
232
``
159
233
`pub fn temp_dir() -> PathBuf {
`