@@ -484,9 +484,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
484
484
}
485
485
let fh = & mut this. machine . file_handler ;
486
486
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)
490
491
} ,
491
492
None => return this. handle_not_found ( ) ,
492
493
} ;
@@ -499,13 +500,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
499
500
{
500
501
let & [ _, _] = check_arg_count ( args) ?;
501
502
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)
509
507
} else {
510
508
this. handle_not_found ( )
511
509
}
@@ -522,28 +520,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
522
520
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
523
521
524
522
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 )
547
542
}
548
543
} else {
549
544
this. handle_not_found ( )
@@ -1223,25 +1218,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1223
1218
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1224
1219
let length = this. read_scalar ( length_op) ?. to_i64 ( ) ?;
1225
1220
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 )
1243
1231
}
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 )
1245
1237
}
1246
1238
} else {
1247
1239
this. handle_not_found ( )
@@ -1260,13 +1252,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1260
1252
1261
1253
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1262
1254
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)
1270
1259
} else {
1271
1260
this. handle_not_found ( )
1272
1261
}
@@ -1279,13 +1268,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1279
1268
1280
1269
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1281
1270
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)
1289
1275
} else {
1290
1276
this. handle_not_found ( )
1291
1277
}
@@ -1322,13 +1308,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1322
1308
}
1323
1309
1324
1310
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)
1332
1315
} else {
1333
1316
this. handle_not_found ( )
1334
1317
}
@@ -1378,10 +1361,7 @@ impl FileMetadata {
1378
1361
) -> InterpResult < ' tcx , Option < FileMetadata > > {
1379
1362
let option = ecx. machine . file_handler . handles . get ( & fd) ;
1380
1363
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 ,
1385
1365
None => return ecx. handle_not_found ( ) . map ( |_: i32 | None ) ,
1386
1366
} ;
1387
1367
let metadata = file. metadata ( ) ;
0 commit comments