@@ -484,9 +484,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
484484 }
485485 let fh = & mut this. machine . file_handler ;
486486 let ( file_result, writable) = match fh. handles . get ( & fd) {
487- Some ( file_descriptor) => match file_descriptor. as_file_handle ( ) {
488- Ok ( FileHandle { file, writable } ) => ( file. try_clone ( ) , * writable) ,
489- Err ( _) => return this. handle_not_found ( ) ,
487+ Some ( file_descriptor) => {
488+ // FIXME: Support "dup" for all FDs(stdin, etc)
489+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
490+ ( file. try_clone ( ) , * writable)
490491 } ,
491492 None => return this. handle_not_found ( ) ,
492493 } ;
@@ -499,13 +500,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
499500 {
500501 let & [ _, _] = check_arg_count ( args) ?;
501502 if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
502- match file_descriptor. as_file_handle ( ) {
503- Ok ( FileHandle { file, writable } ) => {
504- let io_result = maybe_sync_file ( & file, * writable, File :: sync_all) ;
505- this. try_unwrap_io_result ( io_result)
506- } ,
507- Err ( _) => this. handle_not_found ( ) ,
508- }
503+ // FIXME: Support fullfsync for all FDs
504+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
505+ let io_result = maybe_sync_file ( & file, * writable, File :: sync_all) ;
506+ this. try_unwrap_io_result ( io_result)
509507 } else {
510508 this. handle_not_found ( )
511509 }
@@ -522,28 +520,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
522520 let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
523521
524522 if let Some ( file_descriptor) = this. machine . file_handler . handles . remove ( & fd) {
525- match file_descriptor. as_file_handle ( ) {
526- Ok ( FileHandle { file, writable } ) => {
527- // We sync the file if it was opened in a mode different than read-only.
528- if * writable {
529- // `File::sync_all` does the checks that are done when closing a file. We do this to
530- // to handle possible errors correctly.
531- let result = this. try_unwrap_io_result ( file. sync_all ( ) . map ( |_| 0i32 ) ) ;
532- // Now we actually close the file.
533- drop ( file) ;
534- // And return the result.
535- result
536- } else {
537- // We drop the file, this closes it but ignores any errors produced when closing
538- // it. This is done because `File::sync_all` cannot be done over files like
539- // `/dev/urandom` which are read-only. Check
540- // https://github.com/rust-lang/miri/issues/999#issuecomment-568920439 for a deeper
541- // discussion.
542- drop ( file) ;
543- Ok ( 0 )
544- }
545- } ,
546- Err ( _) => this. handle_not_found ( )
523+ // FIXME: Support `close` for all FDs(stdin, etc)
524+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
525+ // We sync the file if it was opened in a mode different than read-only.
526+ if * writable {
527+ // `File::sync_all` does the checks that are done when closing a file. We do this to
528+ // to handle possible errors correctly.
529+ let result = this. try_unwrap_io_result ( file. sync_all ( ) . map ( |_| 0i32 ) ) ;
530+ // Now we actually close the file.
531+ drop ( file) ;
532+ // And return the result.
533+ result
534+ } else {
535+ // We drop the file, this closes it but ignores any errors produced when closing
536+ // it. This is done because `File::sync_all` cannot be done over files like
537+ // `/dev/urandom` which are read-only. Check
538+ // https://github.com/rust-lang/miri/issues/999#issuecomment-568920439 for a deeper
539+ // discussion.
540+ drop ( file) ;
541+ Ok ( 0 )
547542 }
548543 } else {
549544 this. handle_not_found ( )
@@ -1223,25 +1218,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
12231218 let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
12241219 let length = this. read_scalar ( length_op) ?. to_i64 ( ) ?;
12251220 if let Some ( file_descriptor) = this. machine . file_handler . handles . get_mut ( & fd) {
1226- match file_descriptor. as_file_handle ( ) {
1227- Ok ( FileHandle { file, writable } ) => {
1228- if * writable {
1229- if let Ok ( length) = length. try_into ( ) {
1230- let result = file. set_len ( length) ;
1231- this. try_unwrap_io_result ( result. map ( |_| 0i32 ) )
1232- } else {
1233- let einval = this. eval_libc ( "EINVAL" ) ?;
1234- this. set_last_error ( einval) ?;
1235- Ok ( -1 )
1236- }
1237- } else {
1238- // The file is not writable
1239- let einval = this. eval_libc ( "EINVAL" ) ?;
1240- this. set_last_error ( einval) ?;
1241- Ok ( -1 )
1242- }
1221+ // FIXME: Support ftruncate64 for all FDs
1222+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
1223+ if * writable {
1224+ if let Ok ( length) = length. try_into ( ) {
1225+ let result = file. set_len ( length) ;
1226+ this. try_unwrap_io_result ( result. map ( |_| 0i32 ) )
1227+ } else {
1228+ let einval = this. eval_libc ( "EINVAL" ) ?;
1229+ this. set_last_error ( einval) ?;
1230+ Ok ( -1 )
12431231 }
1244- Err ( _) => this. handle_not_found ( )
1232+ } else {
1233+ // The file is not writable
1234+ let einval = this. eval_libc ( "EINVAL" ) ?;
1235+ this. set_last_error ( einval) ?;
1236+ Ok ( -1 )
12451237 }
12461238 } else {
12471239 this. handle_not_found ( )
@@ -1260,13 +1252,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
12601252
12611253 let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
12621254 if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
1263- match file_descriptor. as_file_handle ( ) {
1264- Ok ( FileHandle { file, writable } ) => {
1265- let io_result = maybe_sync_file ( & file, * writable, File :: sync_all) ;
1266- this. try_unwrap_io_result ( io_result)
1267- }
1268- Err ( _) => this. handle_not_found ( )
1269- }
1255+ // FIXME: Support fsync for all FDs
1256+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
1257+ let io_result = maybe_sync_file ( & file, * writable, File :: sync_all) ;
1258+ this. try_unwrap_io_result ( io_result)
12701259 } else {
12711260 this. handle_not_found ( )
12721261 }
@@ -1279,13 +1268,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
12791268
12801269 let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
12811270 if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
1282- match file_descriptor. as_file_handle ( ) {
1283- Ok ( FileHandle { file, writable } ) => {
1284- let io_result = maybe_sync_file ( & file, * writable, File :: sync_data) ;
1285- this. try_unwrap_io_result ( io_result)
1286- }
1287- Err ( _) => this. handle_not_found ( )
1288- }
1271+ // FIXME: Support fdatasync for all FDs
1272+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
1273+ let io_result = maybe_sync_file ( & file, * writable, File :: sync_data) ;
1274+ this. try_unwrap_io_result ( io_result)
12891275 } else {
12901276 this. handle_not_found ( )
12911277 }
@@ -1322,13 +1308,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
13221308 }
13231309
13241310 if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
1325- match file_descriptor. as_file_handle ( ) {
1326- Ok ( FileHandle { file, writable } ) => {
1327- let io_result = maybe_sync_file ( & file, * writable, File :: sync_data) ;
1328- this. try_unwrap_io_result ( io_result)
1329- } ,
1330- Err ( _) => this. handle_not_found ( )
1331- }
1311+ // FIXME: Support sync_data_range for all FDs
1312+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
1313+ let io_result = maybe_sync_file ( & file, * writable, File :: sync_data) ;
1314+ this. try_unwrap_io_result ( io_result)
13321315 } else {
13331316 this. handle_not_found ( )
13341317 }
@@ -1378,10 +1361,7 @@ impl FileMetadata {
13781361 ) -> InterpResult < ' tcx , Option < FileMetadata > > {
13791362 let option = ecx. machine . file_handler . handles . get ( & fd) ;
13801363 let file = match option {
1381- Some ( file_descriptor) => match file_descriptor. as_file_handle ( ) {
1382- Ok ( FileHandle { file, writable : _ } ) => file,
1383- Err ( _) => return ecx. handle_not_found ( ) . map ( |_: i32 | None ) ,
1384- } ,
1364+ Some ( file_descriptor) => & file_descriptor. as_file_handle ( ) ?. file ,
13851365 None => return ecx. handle_not_found ( ) . map ( |_: i32 | None ) ,
13861366 } ;
13871367 let metadata = file. metadata ( ) ;
0 commit comments