@@ -17,6 +17,11 @@ use io;
17
17
use path:: { self , PathBuf } ;
18
18
use str;
19
19
use sys:: { unsupported, Void , sgx_ineffective, decode_error_kind} ;
20
+ use collections:: HashMap ;
21
+ use vec;
22
+ use sync:: Mutex ;
23
+ use sync:: atomic:: { AtomicUsize , Ordering } ;
24
+ use sync:: Once ;
20
25
21
26
pub fn errno ( ) -> i32 {
22
27
RESULT_SUCCESS
@@ -78,29 +83,51 @@ pub fn current_exe() -> io::Result<PathBuf> {
78
83
unsupported ( )
79
84
}
80
85
81
- pub struct Env ;
86
+ static ENV : AtomicUsize = AtomicUsize :: new ( 0 ) ;
87
+ static ENV_INIT : Once = Once :: new ( ) ;
88
+ type EnvStore = Mutex < HashMap < OsString , OsString > > ;
82
89
83
- impl Iterator for Env {
84
- type Item = ( OsString , OsString ) ;
85
- fn next ( & mut self ) -> Option < ( OsString , OsString ) > {
86
- None
90
+ fn get_env_store ( ) -> Option < & ' static EnvStore > {
91
+ unsafe { ( ENV . load ( Ordering :: Relaxed ) as * const EnvStore ) . as_ref ( ) }
92
+ }
93
+
94
+ fn create_env_store ( ) -> & ' static EnvStore {
95
+ ENV_INIT . call_once ( || {
96
+ ENV . store ( Box :: into_raw ( Box :: new ( EnvStore :: default ( ) ) ) as _ , Ordering :: Relaxed )
97
+ } ) ;
98
+ unsafe {
99
+ & * ( ENV . load ( Ordering :: Relaxed ) as * const EnvStore )
87
100
}
88
101
}
89
102
103
+ pub type Env = vec:: IntoIter < ( OsString , OsString ) > ;
104
+
90
105
pub fn env ( ) -> Env {
91
- Env
106
+ let clone_to_vec = |map : & HashMap < OsString , OsString > | -> Vec < _ > {
107
+ map. iter ( ) . map ( |( k, v) | ( k. clone ( ) , v. clone ( ) ) ) . collect ( )
108
+ } ;
109
+
110
+ get_env_store ( )
111
+ . map ( |env| clone_to_vec ( & env. lock ( ) . unwrap ( ) ) )
112
+ . unwrap_or_default ( )
113
+ . into_iter ( )
92
114
}
93
115
94
- pub fn getenv ( _k : & OsStr ) -> io:: Result < Option < OsString > > {
95
- Ok ( None )
116
+ pub fn getenv ( k : & OsStr ) -> io:: Result < Option < OsString > > {
117
+ Ok ( get_env_store ( ) . and_then ( |s| s . lock ( ) . unwrap ( ) . get ( k ) . cloned ( ) ) )
96
118
}
97
119
98
- pub fn setenv ( _k : & OsStr , _v : & OsStr ) -> io:: Result < ( ) > {
99
- sgx_ineffective ( ( ) ) // FIXME: this could trigger a panic higher up the stack
120
+ pub fn setenv ( k : & OsStr , v : & OsStr ) -> io:: Result < ( ) > {
121
+ let ( k, v) = ( k. to_owned ( ) , v. to_owned ( ) ) ;
122
+ create_env_store ( ) . lock ( ) . unwrap ( ) . insert ( k, v) ;
123
+ Ok ( ( ) )
100
124
}
101
125
102
- pub fn unsetenv ( _k : & OsStr ) -> io:: Result < ( ) > {
103
- sgx_ineffective ( ( ) ) // FIXME: this could trigger a panic higher up the stack
126
+ pub fn unsetenv ( k : & OsStr ) -> io:: Result < ( ) > {
127
+ if let Some ( env) = get_env_store ( ) {
128
+ env. lock ( ) . unwrap ( ) . remove ( k) ;
129
+ }
130
+ Ok ( ( ) )
104
131
}
105
132
106
133
pub fn temp_dir ( ) -> PathBuf {
0 commit comments