Skip to content

Commit 39146c4

Browse files
committed
Auto merge of #1130 - christianpoveda:ignore-close-read-only, r=RalfJung
Ignore close errors in read-only files. this fixes #999 r? @RalfJung
2 parents 9f79aa9 + a40a99d commit 39146c4

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

src/shims/env.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,8 @@ pub struct EnvVars {
1818
impl EnvVars {
1919
pub(crate) fn init<'mir, 'tcx>(
2020
ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'tcx>>,
21-
mut excluded_env_vars: Vec<String>,
21+
excluded_env_vars: Vec<String>,
2222
) {
23-
// FIXME: this can be removed when we fix the behavior of the `close` shim for macos.
24-
if ecx.tcx.sess.target.target.target_os.to_lowercase() != "linux" {
25-
// Exclude `TERM` var to avoid terminfo trying to open the termcap file.
26-
excluded_env_vars.push("TERM".to_owned());
27-
}
28-
2923
if ecx.machine.communicate {
3024
for (name, value) in env::vars() {
3125
if !excluded_env_vars.contains(&name) {

src/shims/fs.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use shims::time::system_time_to_duration;
1515
#[derive(Debug)]
1616
pub struct FileHandle {
1717
file: File,
18+
writable: bool,
1819
}
1920

2021
pub struct FileHandler {
@@ -56,10 +57,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5657
if (o_rdonly | o_wronly | o_rdwr) & !0b11 != 0 {
5758
throw_unsup_format!("Access mode flags on this platform are unsupported");
5859
}
60+
let mut writable = true;
61+
5962
// Now we check the access mode
6063
let access_mode = flag & 0b11;
6164

6265
if access_mode == o_rdonly {
66+
writable = false;
6367
options.read(true);
6468
} else if access_mode == o_wronly {
6569
options.write(true);
@@ -105,7 +109,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
105109
let fd = options.open(&path).map(|file| {
106110
let mut fh = &mut this.machine.file_handler;
107111
fh.low += 1;
108-
fh.handles.insert(fh.low, FileHandle { file }).unwrap_none();
112+
fh.handles.insert(fh.low, FileHandle { file, writable }).unwrap_none();
109113
fh.low
110114
});
111115

@@ -148,13 +152,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
148152
let fd = this.read_scalar(fd_op)?.to_i32()?;
149153

150154
if let Some(handle) = this.machine.file_handler.handles.remove(&fd) {
151-
// `File::sync_all` does the checks that are done when closing a file. We do this to
152-
// to handle possible errors correctly.
153-
let result = this.try_unwrap_io_result(handle.file.sync_all().map(|_| 0i32));
154-
// Now we actually close the file.
155-
drop(handle);
156-
// And return the result.
157-
result
155+
// We sync the file if it was opened in a mode different than read-only.
156+
if handle.writable {
157+
// `File::sync_all` does the checks that are done when closing a file. We do this to
158+
// to handle possible errors correctly.
159+
let result = this.try_unwrap_io_result(handle.file.sync_all().map(|_| 0i32));
160+
// Now we actually close the file.
161+
drop(handle);
162+
// And return the result.
163+
result
164+
} else {
165+
// We drop the file, this closes it but ignores any errors produced when closing
166+
// it. This is done because `File::sync_call` cannot be done over files like
167+
// `/dev/urandom` which are read-only. Check
168+
// https://github.com/rust-lang/miri/issues/999#issuecomment-568920439 for a deeper
169+
// discussion.
170+
drop(handle);
171+
Ok(0)
172+
}
158173
} else {
159174
this.handle_not_found()
160175
}

0 commit comments

Comments
 (0)