@@ -7,7 +7,7 @@ use rustc::ty::layout::Size;
7
7
use crate :: stacked_borrows:: Tag ;
8
8
use crate :: * ;
9
9
10
- struct FileHandle {
10
+ pub struct FileHandle {
11
11
file : File ,
12
12
flag : i32 ,
13
13
}
@@ -94,12 +94,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
94
94
}
95
95
Ok ( 0 )
96
96
} else if cmd == this. eval_libc_i32 ( "F_GETFD" ) ? {
97
- if let Some ( handle) = this. machine . file_handler . handles . get ( & fd) {
98
- Ok ( handle. flag )
99
- } else {
100
- this. machine . last_error = this. eval_libc_i32 ( "EBADF" ) ? as u32 ;
101
- Ok ( -1 )
102
- }
97
+ this. get_handle_and ( fd, |handle| Ok ( handle. flag ) , -1 )
103
98
} else {
104
99
throw_unsup_format ! ( "Unsupported command {:#x}" , cmd) ;
105
100
}
@@ -114,12 +109,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
114
109
115
110
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
116
111
117
- if let Some ( handle) = this. machine . file_handler . handles . remove ( & fd) {
118
- this. consume_result :: < i32 > ( handle. file . sync_all ( ) . map ( |_| 0 ) , -1 )
119
- } else {
120
- this. machine . last_error = this. eval_libc_i32 ( "EBADF" ) ? as u32 ;
121
- Ok ( -1 )
122
- }
112
+ this. remove_handle_and (
113
+ fd,
114
+ |handle, this| this. consume_result :: < i32 > ( handle. file . sync_all ( ) . map ( |_| 0 ) , -1 ) ,
115
+ -1 ,
116
+ )
123
117
}
124
118
125
119
fn read (
@@ -141,21 +135,48 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
141
135
let count = this. read_scalar ( count_op) ?. to_usize ( & * this. tcx ) ?;
142
136
143
137
// Remove the file handle to avoid borrowing issues
144
- if let Some ( mut handle) = this. machine . file_handler . handles . remove ( & fd) {
145
- let bytes = handle
146
- . file
147
- . read ( this. memory_mut ( ) . get_mut ( buf. alloc_id ) ?. get_bytes_mut (
148
- tcx,
149
- buf,
150
- Size :: from_bytes ( count) ,
151
- ) ?)
152
- . map ( |bytes| bytes as i64 ) ;
153
- // Reinsert the file handle
154
- this. machine . file_handler . handles . insert ( fd, handle) ;
155
- this. consume_result :: < i64 > ( bytes, -1 )
138
+ this. remove_handle_and (
139
+ fd,
140
+ |mut handle, this| {
141
+ let bytes = handle
142
+ . file
143
+ . read ( this. memory_mut ( ) . get_mut ( buf. alloc_id ) ?. get_bytes_mut (
144
+ tcx,
145
+ buf,
146
+ Size :: from_bytes ( count) ,
147
+ ) ?)
148
+ . map ( |bytes| bytes as i64 ) ;
149
+ // Reinsert the file handle
150
+ this. machine . file_handler . handles . insert ( fd, handle) ;
151
+ this. consume_result :: < i64 > ( bytes, -1 )
152
+ } ,
153
+ -1 ,
154
+ )
155
+ }
156
+
157
+ fn get_handle_and < F , T > ( & mut self , fd : i32 , f : F , t : T ) -> InterpResult < ' tcx , T >
158
+ where
159
+ F : Fn ( & FileHandle ) -> InterpResult < ' tcx , T > ,
160
+ {
161
+ let this = self . eval_context_mut ( ) ;
162
+ if let Some ( handle) = this. machine . file_handler . handles . get ( & fd) {
163
+ f ( handle)
164
+ } else {
165
+ this. machine . last_error = this. eval_libc_i32 ( "EBADF" ) ? as u32 ;
166
+ Ok ( t)
167
+ }
168
+ }
169
+
170
+ fn remove_handle_and < F , T > ( & mut self , fd : i32 , mut f : F , t : T ) -> InterpResult < ' tcx , T >
171
+ where
172
+ F : FnMut ( FileHandle , & mut MiriEvalContext < ' mir , ' tcx > ) -> InterpResult < ' tcx , T > ,
173
+ {
174
+ let this = self . eval_context_mut ( ) ;
175
+ if let Some ( handle) = this. machine . file_handler . handles . remove ( & fd) {
176
+ f ( handle, this)
156
177
} else {
157
178
this. machine . last_error = this. eval_libc_i32 ( "EBADF" ) ? as u32 ;
158
- Ok ( - 1 )
179
+ Ok ( t )
159
180
}
160
181
}
161
182
0 commit comments