@@ -13,15 +13,12 @@ use helpers::immty_from_uint_checked;
13
13
use shims:: time:: system_time_to_duration;
14
14
15
15
#[ derive( Debug ) ]
16
- pub enum FileHandle {
17
- StdInPlaceholder ,
18
- StdOutPlaceholder ,
19
- StdErrPlaceholder ,
20
- File { file : File , writable : bool } ,
21
- // In the future, could add support for dirfd() and other functions by
22
- // adding a Directory variant here
16
+ pub struct FileHandle {
17
+ file : File ,
18
+ writable : bool ,
23
19
}
24
20
21
+ #[ derive( Debug , Default ) ]
25
22
pub struct FileHandler {
26
23
handles : BTreeMap < i32 , FileHandle > ,
27
24
}
@@ -63,17 +60,6 @@ impl FileHandler {
63
60
}
64
61
}
65
62
66
- impl Default for FileHandler {
67
- fn default ( ) -> Self {
68
- let mut handles: BTreeMap < i32 , FileHandle > = Default :: default ( ) ;
69
- // 0, 1 and 2 are reserved for stdin, stdout and stderr.
70
- handles. insert ( 0 , FileHandle :: StdInPlaceholder ) ;
71
- handles. insert ( 1 , FileHandle :: StdOutPlaceholder ) ;
72
- handles. insert ( 2 , FileHandle :: StdErrPlaceholder ) ;
73
- FileHandler { handles }
74
- }
75
- }
76
-
77
63
impl < ' mir , ' tcx > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
78
64
pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
79
65
fn open (
@@ -149,7 +135,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
149
135
150
136
let fd = options. open ( & path) . map ( |file| {
151
137
let fh = & mut this. machine . file_handler ;
152
- fh. insert_fd ( FileHandle :: File { file, writable } )
138
+ fh. insert_fd ( FileHandle { file, writable } )
153
139
} ) ;
154
140
155
141
this. try_unwrap_io_result ( fd)
@@ -185,6 +171,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
185
171
// because exec() isn't supported. The F_DUPFD and F_DUPFD_CLOEXEC commands only
186
172
// differ in whether the FD_CLOEXEC flag is pre-set on the new file descriptor,
187
173
// thus they can share the same implementation here.
174
+ if fd <= 2 {
175
+ throw_unsup_format ! ( "Duplicating file descriptors for stdin, stdout, or stderr is not supported" )
176
+ }
188
177
let start_op = start_op. ok_or_else ( || {
189
178
err_unsup_format ! (
190
179
"fcntl with command F_DUPFD or F_DUPFD_CLOEXEC requires a third argument"
@@ -193,12 +182,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
193
182
let start = this. read_scalar ( start_op) ?. to_i32 ( ) ?;
194
183
let fh = & mut this. machine . file_handler ;
195
184
let ( file_result, writable) = match fh. handles . get ( & fd) {
196
- Some ( FileHandle :: File { file, writable } ) => ( file. try_clone ( ) , * writable) ,
197
- Some ( _) => throw_unsup_format ! ( "Duplicating file descriptors for stdin, stdout, or stderr is not supported" ) ,
185
+ Some ( FileHandle { file, writable } ) => ( file. try_clone ( ) , * writable) ,
198
186
None => return this. handle_not_found ( ) ,
199
187
} ;
200
188
let fd_result = file_result. map ( |duplicated| {
201
- fh. insert_fd_with_min_fd ( FileHandle :: File { file : duplicated, writable } , start)
189
+ fh. insert_fd_with_min_fd ( FileHandle { file : duplicated, writable } , start)
202
190
} ) ;
203
191
this. try_unwrap_io_result ( fd_result)
204
192
} else {
@@ -213,12 +201,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
213
201
214
202
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
215
203
216
- if fd <= 2 {
217
- // early return to prevent removing StdInPlaceholder, etc., from the handles map
218
- return this. handle_not_found ( ) ;
219
- }
220
-
221
- if let Some ( FileHandle :: File { file, writable } ) = this. machine . file_handler . handles . remove ( & fd) {
204
+ if let Some ( FileHandle { file, writable } ) = this. machine . file_handler . handles . remove ( & fd) {
222
205
// We sync the file if it was opened in a mode different than read-only.
223
206
if writable {
224
207
// `File::sync_all` does the checks that are done when closing a file. We do this to
@@ -267,7 +250,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
267
250
// host's and target's `isize`. This saves us from having to handle overflows later.
268
251
let count = count. min ( this. isize_max ( ) as u64 ) . min ( isize:: max_value ( ) as u64 ) ;
269
252
270
- if let Some ( FileHandle :: File { file, writable : _ } ) = this. machine . file_handler . handles . get_mut ( & fd) {
253
+ if let Some ( FileHandle { file, writable : _ } ) = this. machine . file_handler . handles . get_mut ( & fd) {
271
254
// This can never fail because `count` was capped to be smaller than
272
255
// `isize::max_value()`.
273
256
let count = isize:: try_from ( count) . unwrap ( ) ;
@@ -321,7 +304,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
321
304
// host's and target's `isize`. This saves us from having to handle overflows later.
322
305
let count = count. min ( this. isize_max ( ) as u64 ) . min ( isize:: max_value ( ) as u64 ) ;
323
306
324
- if let Some ( FileHandle :: File { file, writable : _ } ) = this. machine . file_handler . handles . get_mut ( & fd) {
307
+ if let Some ( FileHandle { file, writable : _ } ) = this. machine . file_handler . handles . get_mut ( & fd) {
325
308
let bytes = this. memory . read_bytes ( buf, Size :: from_bytes ( count) ) ?;
326
309
let result = file. write ( & bytes) . map ( |c| i64:: try_from ( c) . unwrap ( ) ) ;
327
310
this. try_unwrap_io_result ( result)
@@ -356,7 +339,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
356
339
return Ok ( -1 ) ;
357
340
} ;
358
341
359
- if let Some ( FileHandle :: File { file, writable : _ } ) = this. machine . file_handler . handles . get_mut ( & fd) {
342
+ if let Some ( FileHandle { file, writable : _ } ) = this. machine . file_handler . handles . get_mut ( & fd) {
360
343
let result = file. seek ( seek_from) . map ( |offset| offset as i64 ) ;
361
344
this. try_unwrap_io_result ( result)
362
345
} else {
@@ -719,8 +702,8 @@ impl FileMetadata {
719
702
) -> InterpResult < ' tcx , Option < FileMetadata > > {
720
703
let option = ecx. machine . file_handler . handles . get ( & fd) ;
721
704
let file = match option {
722
- Some ( FileHandle :: File { file, writable : _ } ) => file,
723
- Some ( _ ) | None => return ecx. handle_not_found ( ) . map ( |_: i32 | None ) ,
705
+ Some ( FileHandle { file, writable : _ } ) => file,
706
+ None => return ecx. handle_not_found ( ) . map ( |_: i32 | None ) ,
724
707
} ;
725
708
let metadata = file. metadata ( ) ;
726
709
0 commit comments