@@ -17,6 +17,11 @@ use io;
1717use path:: { self , PathBuf } ;
1818use str;
1919use 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 ;
2025
2126pub fn errno ( ) -> i32 {
2227 RESULT_SUCCESS
@@ -78,29 +83,51 @@ pub fn current_exe() -> io::Result<PathBuf> {
7883 unsupported ( )
7984}
8085
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 > > ;
8289
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 )
87100 }
88101}
89102
103+ pub type Env = vec:: IntoIter < ( OsString , OsString ) > ;
104+
90105pub 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 ( )
92114}
93115
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 ( ) ) )
96118}
97119
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 ( ( ) )
100124}
101125
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 ( ( ) )
104131}
105132
106133pub fn temp_dir ( ) -> PathBuf {
0 commit comments