1
1
use std:: collections:: HashMap ;
2
2
use std:: env;
3
3
4
- use rustc:: ty:: layout:: { Size } ;
5
- use rustc_mir:: interpret:: { Pointer , Memory } ;
6
4
use crate :: stacked_borrows:: Tag ;
7
5
use crate :: * ;
6
+ use rustc:: ty:: layout:: Size ;
7
+ use rustc_mir:: interpret:: { Memory , Pointer } ;
8
8
9
9
#[ derive( Default ) ]
10
10
pub struct EnvVars {
@@ -24,7 +24,8 @@ impl EnvVars {
24
24
if ecx. machine . communicate {
25
25
for ( name, value) in env:: vars ( ) {
26
26
if !excluded_env_vars. contains ( & name) {
27
- let var_ptr = alloc_env_var ( name. as_bytes ( ) , value. as_bytes ( ) , ecx. memory_mut ( ) ) ;
27
+ let var_ptr =
28
+ alloc_env_var ( name. as_bytes ( ) , value. as_bytes ( ) , ecx. memory_mut ( ) ) ;
28
29
ecx. machine . env_vars . map . insert ( name. into_bytes ( ) , var_ptr) ;
29
30
}
30
31
}
@@ -46,17 +47,16 @@ fn alloc_env_var<'mir, 'tcx>(
46
47
47
48
impl < ' mir , ' tcx > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
48
49
pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
49
- fn getenv (
50
- & mut self ,
51
- name_op : OpTy < ' tcx , Tag > ,
52
- ) -> InterpResult < ' tcx , Scalar < Tag > > {
50
+ fn getenv ( & mut self , name_op : OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , Scalar < Tag > > {
53
51
let this = self . eval_context_mut ( ) ;
54
52
55
53
let name_ptr = this. read_scalar ( name_op) ?. not_undef ( ) ?;
56
54
let name = this. memory ( ) . read_c_str ( name_ptr) ?;
57
55
Ok ( match this. machine . env_vars . map . get ( name) {
58
56
// The offset is used to strip the "{name}=" part of the string.
59
- Some ( var_ptr) => Scalar :: Ptr ( var_ptr. offset ( Size :: from_bytes ( name. len ( ) as u64 + 1 ) , this) ?) ,
57
+ Some ( var_ptr) => {
58
+ Scalar :: Ptr ( var_ptr. offset ( Size :: from_bytes ( name. len ( ) as u64 + 1 ) , this) ?)
59
+ }
60
60
None => Scalar :: ptr_null ( & * this. tcx ) ,
61
61
} )
62
62
}
@@ -81,18 +81,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
81
81
if let Some ( ( name, value) ) = new {
82
82
let var_ptr = alloc_env_var ( & name, & value, this. memory_mut ( ) ) ;
83
83
if let Some ( var) = this. machine . env_vars . map . insert ( name. to_owned ( ) , var_ptr) {
84
- this. memory_mut ( ) . deallocate ( var, None , MiriMemoryKind :: Env . into ( ) ) ?;
84
+ this. memory_mut ( )
85
+ . deallocate ( var, None , MiriMemoryKind :: Env . into ( ) ) ?;
85
86
}
86
87
Ok ( 0 )
87
88
} else {
88
89
Ok ( -1 )
89
90
}
90
91
}
91
92
92
- fn unsetenv (
93
- & mut self ,
94
- name_op : OpTy < ' tcx , Tag > ,
95
- ) -> InterpResult < ' tcx , i32 > {
93
+ fn unsetenv ( & mut self , name_op : OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
96
94
let this = self . eval_context_mut ( ) ;
97
95
98
96
let name_ptr = this. read_scalar ( name_op) ?. not_undef ( ) ?;
@@ -105,7 +103,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
105
103
}
106
104
if let Some ( old) = success {
107
105
if let Some ( var) = old {
108
- this. memory_mut ( ) . deallocate ( var, None , MiriMemoryKind :: Env . into ( ) ) ?;
106
+ this. memory_mut ( )
107
+ . deallocate ( var, None , MiriMemoryKind :: Env . into ( ) ) ?;
109
108
}
110
109
Ok ( 0 )
111
110
} else {
@@ -124,25 +123,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
124
123
throw_unsup_format ! ( "Function not available when isolation is enabled" )
125
124
}
126
125
127
- let tcx = & { this. tcx . tcx } ;
126
+ let tcx = & { this. tcx . tcx } ;
128
127
129
128
let buf = this. force_ptr ( this. read_scalar ( buf_op) ?. not_undef ( ) ?) ?;
130
129
let size = this. read_scalar ( size_op) ?. to_usize ( & * this. tcx ) ?;
131
130
// If we cannot get the current directory, we return null
132
131
// FIXME: Technically we have to set the `errno` global too
133
132
match env:: current_dir ( ) {
134
- Ok ( cwd) =>{
133
+ Ok ( cwd) => {
135
134
// It is not clear what happens with non-utf8 paths here
136
135
let mut bytes = cwd. display ( ) . to_string ( ) . into_bytes ( ) ;
137
136
// If the buffer is smaller or equal than the path, we return null.
138
137
if ( bytes. len ( ) as u64 ) < size {
139
138
// We add a `/0` terminator
140
139
bytes. push ( 0 ) ;
141
140
// This is ok because the buffer is larger than the path with the null terminator.
142
- this. memory_mut ( ) . get_mut ( buf. alloc_id ) ?. write_bytes ( tcx, buf, & bytes) ?;
143
- return Ok ( Scalar :: Ptr ( buf) )
141
+ this. memory_mut ( )
142
+ . get_mut ( buf. alloc_id ) ?
143
+ . write_bytes ( tcx, buf, & bytes) ?;
144
+ return Ok ( Scalar :: Ptr ( buf) ) ;
144
145
}
145
- this. machine . last_error = 34 ; // ERANGE
146
+ this. machine . last_error = this
147
+ . eval_path_scalar ( & [ "libc" , "ERANGE" ] ) ?
148
+ . unwrap ( )
149
+ . to_u32 ( ) ?;
146
150
}
147
151
Err ( e) => this. machine . last_error = e. raw_os_error ( ) . unwrap ( ) as u32 ,
148
152
}
0 commit comments