@@ -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,7 @@ 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. get_handle_and ( fd, |handle| Ok ( handle. flag ) , -1 )
10398 } else {
10499 throw_unsup_format ! ( "Unsupported command {:#x}" , cmd) ;
105100 }
@@ -114,12 +109,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
114109
115110 let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
116111
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+ )
123117 }
124118
125119 fn read (
@@ -141,21 +135,48 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
141135 let count = this. read_scalar ( count_op) ?. to_usize ( & * this. tcx ) ?;
142136
143137 // 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)
156177 } else {
157178 this. machine . last_error = this. eval_libc_i32 ( "EBADF" ) ? as u32 ;
158- Ok ( - 1 )
179+ Ok ( t )
159180 }
160181 }
161182
0 commit comments