@@ -7,7 +7,7 @@ use rustc::ty::layout::Size;
77use crate :: stacked_borrows:: Tag ;
88use crate :: * ;
99
10- struct FileHandle {
10+ pub struct FileHandle {
1111 file : File ,
1212 flag : i32 ,
1313}
@@ -94,12 +94,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9494 }
9595 Ok ( 0 )
9696 } 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+ )
103106 } else {
104107 throw_unsup_format ! ( "Unsupported command {:#x}" , cmd) ;
105108 }
@@ -114,12 +117,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
114117
115118 let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
116119
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+ )
123125 }
124126
125127 fn read (
@@ -141,21 +143,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
141143 let count = this. read_scalar ( count_op) ?. to_usize ( & * this. tcx ) ?;
142144
143145 // 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)
156172 } else {
157173 this. machine . last_error = this. eval_libc_i32 ( "EBADF" ) ? as u32 ;
158- Ok ( - 1 )
174+ Ok ( t )
159175 }
160176 }
161177
0 commit comments