@@ -484,9 +484,9 @@ 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+ let FileHandle { file, writable } = file_descriptor . as_file_handle ( ) ? ;
489+ ( file . try_clone ( ) , * writable )
490490 } ,
491491 None => return this. handle_not_found ( ) ,
492492 } ;
@@ -522,28 +522,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
522522 let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
523523
524524 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 ( )
525+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
526+ // We sync the file if it was opened in a mode different than read-only.
527+ if * writable {
528+ // `File::sync_all` does the checks that are done when closing a file. We do this to
529+ // to handle possible errors correctly.
530+ let result = this. try_unwrap_io_result ( file. sync_all ( ) . map ( |_| 0i32 ) ) ;
531+ // Now we actually close the file.
532+ drop ( file) ;
533+ // And return the result.
534+ result
535+ } else {
536+ // We drop the file, this closes it but ignores any errors produced when closing
537+ // it. This is done because `File::sync_all` cannot be done over files like
538+ // `/dev/urandom` which are read-only. Check
539+ // https://github.com/rust-lang/miri/issues/999#issuecomment-568920439 for a deeper
540+ // discussion.
541+ drop ( file) ;
542+ Ok ( 0 )
547543 }
548544 } else {
549545 this. handle_not_found ( )
@@ -1223,25 +1219,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
12231219 let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
12241220 let length = this. read_scalar ( length_op) ?. to_i64 ( ) ?;
12251221 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- }
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,9 @@ 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+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
1256+ let io_result = maybe_sync_file ( & file, * writable, File :: sync_all) ;
1257+ this. try_unwrap_io_result ( io_result)
12701258 } else {
12711259 this. handle_not_found ( )
12721260 }
@@ -1279,13 +1267,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
12791267
12801268 let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
12811269 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- }
1270+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
1271+ let io_result = maybe_sync_file ( & file, * writable, File :: sync_data) ;
1272+ this. try_unwrap_io_result ( io_result)
12891273 } else {
12901274 this. handle_not_found ( )
12911275 }
@@ -1322,13 +1306,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
13221306 }
13231307
13241308 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- }
1309+ let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
1310+ let io_result = maybe_sync_file ( & file, * writable, File :: sync_data) ;
1311+ this. try_unwrap_io_result ( io_result)
13321312 } else {
13331313 this. handle_not_found ( )
13341314 }
@@ -1378,9 +1358,9 @@ impl FileMetadata {
13781358 ) -> InterpResult < ' tcx , Option < FileMetadata > > {
13791359 let option = ecx. machine . file_handler . handles . get ( & fd) ;
13801360 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 ) ,
1361+ Some ( file_descriptor) => {
1362+ let FileHandle { file, writable : _ } = file_descriptor . as_file_handle ( ) ? ;
1363+ file
13841364 } ,
13851365 None => return ecx. handle_not_found ( ) . map ( |_: i32 | None ) ,
13861366 } ;
0 commit comments