11use std:: collections:: HashMap ;
2+ use std:: env;
23
34use rustc:: ty:: layout:: { Size } ;
45use rustc_mir:: interpret:: { Pointer , Memory } ;
@@ -21,7 +22,7 @@ impl EnvVars {
2122 excluded_env_vars. push ( "TERM" . to_owned ( ) ) ;
2223
2324 if ecx. machine . communicate {
24- for ( name, value) in std :: env:: vars ( ) {
25+ for ( name, value) in env:: vars ( ) {
2526 if !excluded_env_vars. contains ( & name) {
2627 let var_ptr = alloc_env_var ( name. as_bytes ( ) , value. as_bytes ( ) , ecx. memory_mut ( ) ) ;
2728 ecx. machine . env_vars . map . insert ( name. into_bytes ( ) , var_ptr) ;
@@ -111,4 +112,31 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
111112 Ok ( -1 )
112113 }
113114 }
115+
116+ fn getcwd (
117+ & mut self ,
118+ buf_op : OpTy < ' tcx , Tag > ,
119+ size_op : OpTy < ' tcx , Tag > ,
120+ ) -> InterpResult < ' tcx , Scalar < Tag > > {
121+ let this = self . eval_context_mut ( ) ;
122+
123+ let buf = this. read_scalar ( buf_op) ?. not_undef ( ) ?. assert_ptr ( ) ;
124+ let size = this. read_scalar ( size_op) ?. to_usize ( & * this. tcx ) ?;
125+ // If we cannot get the current directory, we return null
126+ if let Ok ( cwd) = env:: current_dir ( ) {
127+ // It is not clear what happens with non-utf8 paths here
128+ let mut bytes = cwd. display ( ) . to_string ( ) . into_bytes ( ) ;
129+ // If the buffer is smaller than the path, we return null
130+ if bytes. len ( ) as u64 <= size {
131+ bytes. resize ( size as usize , 0 ) ;
132+ // Temporary pointer to write the path into miri's memory
133+ let ptr = this. memory_mut ( ) . allocate_static_bytes ( bytes. as_slice ( ) , MiriMemoryKind :: Env . into ( ) ) ;
134+ this. memory_mut ( ) . copy ( ptr, buf, Size :: from_bytes ( size) , true ) ?;
135+ // Deallocate the temporary pointer
136+ this. memory_mut ( ) . deallocate ( ptr, None , MiriMemoryKind :: Env . into ( ) ) ?;
137+ return Ok ( Scalar :: Ptr ( buf) )
138+ }
139+ }
140+ Ok ( Scalar :: ptr_null ( & * this. tcx ) )
141+ }
114142}
0 commit comments