This repository was archived by the owner on May 28, 2025. It is now read-only.
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 {
130
130
let mut default_crate_root: Option < FileId > = None ;
131
131
let mut default_target_data_layout: Option < String > = None ;
132
132
let mut default_cfg = CfgOptions :: default ( ) ;
133
+ let mut default_env = Env :: new_for_test_fixture ( ) ;
133
134
134
135
let mut file_set = FileSet :: default ( ) ;
135
136
let mut current_source_root_kind = SourceRootKind :: Local ;
@@ -200,6 +201,7 @@ impl ChangeFixture {
200
201
assert ! ( default_crate_root. is_none( ) ) ;
201
202
default_crate_root = Some ( file_id) ;
202
203
default_cfg = meta. cfg ;
204
+ default_env. extend ( meta. env . iter ( ) . map ( |( x, y) | ( x. to_owned ( ) , y. to_owned ( ) ) ) ) ;
203
205
default_target_data_layout = meta. target_data_layout ;
204
206
}
205
207
@@ -220,7 +222,7 @@ impl ChangeFixture {
220
222
None ,
221
223
default_cfg,
222
224
Default :: default ( ) ,
223
- Env :: new_for_test_fixture ( ) ,
225
+ default_env ,
224
226
false ,
225
227
CrateOrigin :: Local { repo : None , name : None } ,
226
228
default_target_data_layout
Original file line number Diff line number Diff line change @@ -686,6 +686,12 @@ impl fmt::Display for Edition {
686
686
}
687
687
}
688
688
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
+
689
695
impl FromIterator < ( String , String ) > for Env {
690
696
fn from_iter < T : IntoIterator < Item = ( String , String ) > > ( iter : T ) -> Self {
691
697
Env { entries : FromIterator :: from_iter ( iter) }
Original file line number Diff line number Diff line change @@ -473,6 +473,38 @@ impl Evaluator<'_> {
473
473
self . write_memory_using_ref ( destination. addr , destination. size ) ?. fill ( 0 ) ;
474
474
Ok ( ( ) )
475
475
}
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
+ }
476
508
_ => not_supported ! ( "unknown external function {as_str}" ) ,
477
509
}
478
510
}
Original file line number Diff line number Diff line change @@ -729,6 +729,48 @@ fn main() {
729
729
)
730
730
}
731
731
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
+
732
774
#[ test]
733
775
fn posix_tls ( ) {
734
776
check_pass (
You can’t perform that action at this time.
0 commit comments