@@ -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,15 @@ 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. take_file (
98
+ fd,
99
+ |handle, this| {
100
+ let flag = handle. flag ;
101
+ this. machine . file_handler . handles . insert ( fd, handle) ;
102
+ Ok ( flag)
103
+ } ,
104
+ -1 ,
105
+ )
103
106
} else {
104
107
throw_unsup_format ! ( "Unsupported command {:#x}" , cmd) ;
105
108
}
@@ -114,12 +117,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
114
117
115
118
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
116
119
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
- }
120
+ this. take_file (
121
+ fd,
122
+ |handle, this| this. consume_result :: < i32 > ( handle. file . sync_all ( ) . map ( |_| 0 ) , -1 ) ,
123
+ -1 ,
124
+ )
123
125
}
124
126
125
127
fn read (
@@ -141,21 +143,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
141
143
let count = this. read_scalar ( count_op) ?. to_usize ( & * this. tcx ) ?;
142
144
143
145
// 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 )
146
+ this. take_file (
147
+ fd,
148
+ |mut handle, this| {
149
+ let bytes = handle
150
+ . file
151
+ . read ( this. memory_mut ( ) . get_mut ( buf. alloc_id ) ?. get_bytes_mut (
152
+ tcx,
153
+ buf,
154
+ Size :: from_bytes ( count) ,
155
+ ) ?)
156
+ . map ( |bytes| bytes as i64 ) ;
157
+ // Reinsert the file handle
158
+ this. machine . file_handler . handles . insert ( fd, handle) ;
159
+ this. consume_result :: < i64 > ( bytes, -1 )
160
+ } ,
161
+ -1 ,
162
+ )
163
+ }
164
+
165
+ fn take_file < F , T > ( & mut self , fd : i32 , mut f : F , t : T ) -> InterpResult < ' tcx , T >
166
+ where
167
+ F : FnMut ( FileHandle , & mut MiriEvalContext < ' mir , ' tcx > ) -> InterpResult < ' tcx , T > ,
168
+ {
169
+ let this = self . eval_context_mut ( ) ;
170
+ if let Some ( handle) = this. machine . file_handler . handles . remove ( & fd) {
171
+ f ( handle, this)
156
172
} else {
157
173
this. machine . last_error = this. eval_libc_i32 ( "EBADF" ) ? as u32 ;
158
- Ok ( - 1 )
174
+ Ok ( t )
159
175
}
160
176
}
161
177
0 commit comments