File tree Expand file tree Collapse file tree 4 files changed +83
-1
lines changed Expand file tree Collapse file tree 4 files changed +83
-1
lines changed Original file line number Diff line number Diff line change @@ -130,6 +130,7 @@ impl ChangeFixture {
130130 let mut default_crate_root: Option < FileId > = None ;
131131 let mut default_target_data_layout: Option < String > = None ;
132132 let mut default_cfg = CfgOptions :: default ( ) ;
133+ let mut default_env = Env :: new_for_test_fixture ( ) ;
133134
134135 let mut file_set = FileSet :: default ( ) ;
135136 let mut current_source_root_kind = SourceRootKind :: Local ;
@@ -200,6 +201,7 @@ impl ChangeFixture {
200201 assert ! ( default_crate_root. is_none( ) ) ;
201202 default_crate_root = Some ( file_id) ;
202203 default_cfg = meta. cfg ;
204+ default_env. extend ( meta. env . iter ( ) . map ( |( x, y) | ( x. to_owned ( ) , y. to_owned ( ) ) ) ) ;
203205 default_target_data_layout = meta. target_data_layout ;
204206 }
205207
@@ -220,7 +222,7 @@ impl ChangeFixture {
220222 None ,
221223 default_cfg,
222224 Default :: default ( ) ,
223- Env :: new_for_test_fixture ( ) ,
225+ default_env ,
224226 false ,
225227 CrateOrigin :: Local { repo : None , name : None } ,
226228 default_target_data_layout
Original file line number Diff line number Diff line change @@ -686,6 +686,12 @@ impl fmt::Display for Edition {
686686 }
687687}
688688
689+ impl Extend < ( String , String ) > for Env {
690+ fn extend < T : IntoIterator < Item = ( String , String ) > > ( & mut self , iter : T ) {
691+ self . entries . extend ( iter) ;
692+ }
693+ }
694+
689695impl FromIterator < ( String , String ) > for Env {
690696 fn from_iter < T : IntoIterator < Item = ( String , String ) > > ( iter : T ) -> Self {
691697 Env { entries : FromIterator :: from_iter ( iter) }
Original file line number Diff line number Diff line change @@ -473,6 +473,38 @@ impl Evaluator<'_> {
473473 self . write_memory_using_ref ( destination. addr , destination. size ) ?. fill ( 0 ) ;
474474 Ok ( ( ) )
475475 }
476+ "getenv" => {
477+ let [ name] = args else {
478+ return Err ( MirEvalError :: TypeError ( "libc::write args are not provided" ) ) ;
479+ } ;
480+ let mut name_buf = vec ! [ ] ;
481+ let name = {
482+ let mut index = Address :: from_bytes ( name. get ( self ) ?) ?;
483+ loop {
484+ let byte = self . read_memory ( index, 1 ) ?[ 0 ] ;
485+ index = index. offset ( 1 ) ;
486+ if byte == 0 {
487+ break ;
488+ }
489+ name_buf. push ( byte) ;
490+ }
491+ String :: from_utf8_lossy ( & name_buf)
492+ } ;
493+ let value = self . db . crate_graph ( ) [ self . crate_id ] . env . get ( & name) ;
494+ match value {
495+ None => {
496+ // Write null as fail
497+ self . write_memory_using_ref ( destination. addr , destination. size ) ?. fill ( 0 ) ;
498+ }
499+ Some ( mut value) => {
500+ value. push ( '\0' ) ;
501+ let addr = self . heap_allocate ( value. len ( ) , 1 ) ?;
502+ self . write_memory ( addr, value. as_bytes ( ) ) ?;
503+ self . write_memory ( destination. addr , & addr. to_bytes ( ) ) ?;
504+ }
505+ }
506+ Ok ( ( ) )
507+ }
476508 _ => not_supported ! ( "unknown external function {as_str}" ) ,
477509 }
478510 }
Original file line number Diff line number Diff line change @@ -729,6 +729,48 @@ fn main() {
729729 )
730730}
731731
732+ #[ test]
733+ fn posix_getenv ( ) {
734+ check_pass (
735+ r#"
736+ //- /main.rs env:foo=bar
737+
738+ type c_char = u8;
739+
740+ extern "C" {
741+ pub fn getenv(s: *const c_char) -> *mut c_char;
742+ }
743+
744+ fn should_not_reach() {
745+ _ // FIXME: replace this function with panic when that works
746+ }
747+
748+ fn main() {
749+ let result = getenv(b"foo\0" as *const _);
750+ if *result != b'b' {
751+ should_not_reach();
752+ }
753+ let result = (result as usize + 1) as *const c_char;
754+ if *result != b'a' {
755+ should_not_reach();
756+ }
757+ let result = (result as usize + 1) as *const c_char;
758+ if *result != b'r' {
759+ should_not_reach();
760+ }
761+ let result = (result as usize + 1) as *const c_char;
762+ if *result != 0 {
763+ should_not_reach();
764+ }
765+ let result = getenv(b"not found\0" as *const _);
766+ if result as usize != 0 {
767+ should_not_reach();
768+ }
769+ }
770+ "# ,
771+ ) ;
772+ }
773+
732774#[ test]
733775fn posix_tls ( ) {
734776 check_pass (
You can’t perform that action at this time.
0 commit comments