|
1 | | -// FIXME: this module systematically confuses pointers and integers |
2 | | -#![allow(fuzzy_provenance_casts, lossy_provenance_casts)] |
3 | | - |
4 | 1 | pub use super::common::Env; |
5 | 2 | use crate::collections::HashMap; |
6 | 3 | use crate::ffi::{OsStr, OsString}; |
7 | 4 | use crate::io; |
8 | | -use crate::sync::atomic::{Atomic, AtomicUsize, Ordering}; |
9 | | -use crate::sync::{Mutex, Once}; |
| 5 | +use crate::sync::{Mutex, OnceLock}; |
| 6 | + |
| 7 | +type EnvStore = Mutex<HashMap<OsString, OsString>>; |
10 | 8 |
|
11 | 9 | // Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests |
12 | 10 | #[cfg_attr(test, linkage = "available_externally")] |
13 | 11 | #[unsafe(export_name = "_ZN16__rust_internals3std3sys3pal3sgx2os3ENVE")] |
14 | | -static ENV: Atomic<usize> = AtomicUsize::new(0); |
15 | | -// Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests |
16 | | -#[cfg_attr(test, linkage = "available_externally")] |
17 | | -#[unsafe(export_name = "_ZN16__rust_internals3std3sys3pal3sgx2os8ENV_INITE")] |
18 | | -static ENV_INIT: Once = Once::new(); |
19 | | -type EnvStore = Mutex<HashMap<OsString, OsString>>; |
20 | | - |
21 | | -fn get_env_store() -> Option<&'static EnvStore> { |
22 | | - unsafe { (ENV.load(Ordering::Relaxed) as *const EnvStore).as_ref() } |
23 | | -} |
24 | | - |
25 | | -fn create_env_store() -> &'static EnvStore { |
26 | | - ENV_INIT.call_once(|| { |
27 | | - ENV.store(Box::into_raw(Box::new(EnvStore::default())) as _, Ordering::Relaxed) |
28 | | - }); |
29 | | - unsafe { &*(ENV.load(Ordering::Relaxed) as *const EnvStore) } |
30 | | -} |
| 12 | +static ENV: OnceLock<EnvStore> = OnceLock::new(); |
31 | 13 |
|
32 | 14 | pub fn env() -> Env { |
33 | | - let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> { |
34 | | - map.iter().map(|(k, v)| (k.clone(), v.clone())).collect() |
35 | | - }; |
36 | | - |
37 | | - let env = get_env_store().map(|env| clone_to_vec(&env.lock().unwrap())).unwrap_or_default(); |
| 15 | + let env = ENV |
| 16 | + .get() |
| 17 | + .map(|env| env.lock().unwrap().iter().map(|(k, v)| (k.clone(), v.clone())).collect()) |
| 18 | + .unwrap_or_default(); |
38 | 19 | Env::new(env) |
39 | 20 | } |
40 | 21 |
|
41 | 22 | pub fn getenv(k: &OsStr) -> Option<OsString> { |
42 | | - get_env_store().and_then(|s| s.lock().unwrap().get(k).cloned()) |
| 23 | + ENV.get().and_then(|s| s.lock().unwrap().get(k).cloned()) |
43 | 24 | } |
44 | 25 |
|
45 | 26 | pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { |
46 | | - let (k, v) = (k.to_owned(), v.to_owned()); |
47 | | - create_env_store().lock().unwrap().insert(k, v); |
| 27 | + ENV.get_or_init(|| EnvStore::default()).lock().unwrap().insert(k.to_owned(), v.to_owned()); |
48 | 28 | Ok(()) |
49 | 29 | } |
50 | 30 |
|
51 | 31 | pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> { |
52 | | - if let Some(env) = get_env_store() { |
| 32 | + if let Some(env) = ENV.get() { |
53 | 33 | env.lock().unwrap().remove(k); |
54 | 34 | } |
55 | 35 | Ok(()) |
|
0 commit comments