Skip to content

Commit 773dfb3

Browse files
committed
Bubble up error from FileDescriptor::as_file_handle
...instead of handle_not_found
1 parent cf633d0 commit 773dfb3

File tree

1 file changed

+47
-67
lines changed

1 file changed

+47
-67
lines changed

src/shims/posix/fs.rs

Lines changed: 47 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)