Skip to content

Commit 8216f3c

Browse files
committed
Back out placeholder variants from FileHandle
1 parent a6a8f09 commit 8216f3c

File tree

1 file changed

+16
-33
lines changed

1 file changed

+16
-33
lines changed

src/shims/fs.rs

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,12 @@ use helpers::immty_from_uint_checked;
1313
use shims::time::system_time_to_duration;
1414

1515
#[derive(Debug)]
16-
pub enum FileHandle {
17-
StdInPlaceholder,
18-
StdOutPlaceholder,
19-
StdErrPlaceholder,
20-
File { file: File, writable: bool },
21-
// In the future, could add support for dirfd() and other functions by
22-
// adding a Directory variant here
16+
pub struct FileHandle {
17+
file: File,
18+
writable: bool,
2319
}
2420

21+
#[derive(Debug, Default)]
2522
pub struct FileHandler {
2623
handles: BTreeMap<i32, FileHandle>,
2724
}
@@ -63,17 +60,6 @@ impl FileHandler {
6360
}
6461
}
6562

66-
impl Default for FileHandler {
67-
fn default() -> Self {
68-
let mut handles: BTreeMap<i32, FileHandle> = Default::default();
69-
// 0, 1 and 2 are reserved for stdin, stdout and stderr.
70-
handles.insert(0, FileHandle::StdInPlaceholder);
71-
handles.insert(1, FileHandle::StdOutPlaceholder);
72-
handles.insert(2, FileHandle::StdErrPlaceholder);
73-
FileHandler { handles }
74-
}
75-
}
76-
7763
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
7864
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
7965
fn open(
@@ -149,7 +135,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
149135

150136
let fd = options.open(&path).map(|file| {
151137
let fh = &mut this.machine.file_handler;
152-
fh.insert_fd(FileHandle::File { file, writable })
138+
fh.insert_fd(FileHandle { file, writable })
153139
});
154140

155141
this.try_unwrap_io_result(fd)
@@ -185,6 +171,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
185171
// because exec() isn't supported. The F_DUPFD and F_DUPFD_CLOEXEC commands only
186172
// differ in whether the FD_CLOEXEC flag is pre-set on the new file descriptor,
187173
// thus they can share the same implementation here.
174+
if fd <= 2 {
175+
throw_unsup_format!("Duplicating file descriptors for stdin, stdout, or stderr is not supported")
176+
}
188177
let start_op = start_op.ok_or_else(|| {
189178
err_unsup_format!(
190179
"fcntl with command F_DUPFD or F_DUPFD_CLOEXEC requires a third argument"
@@ -193,12 +182,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
193182
let start = this.read_scalar(start_op)?.to_i32()?;
194183
let fh = &mut this.machine.file_handler;
195184
let (file_result, writable) = match fh.handles.get(&fd) {
196-
Some(FileHandle::File { file, writable }) => (file.try_clone(), *writable),
197-
Some(_) => throw_unsup_format!("Duplicating file descriptors for stdin, stdout, or stderr is not supported"),
185+
Some(FileHandle { file, writable }) => (file.try_clone(), *writable),
198186
None => return this.handle_not_found(),
199187
};
200188
let fd_result = file_result.map(|duplicated| {
201-
fh.insert_fd_with_min_fd(FileHandle::File { file: duplicated, writable }, start)
189+
fh.insert_fd_with_min_fd(FileHandle { file: duplicated, writable }, start)
202190
});
203191
this.try_unwrap_io_result(fd_result)
204192
} else {
@@ -213,12 +201,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
213201

214202
let fd = this.read_scalar(fd_op)?.to_i32()?;
215203

216-
if fd <= 2 {
217-
// early return to prevent removing StdInPlaceholder, etc., from the handles map
218-
return this.handle_not_found();
219-
}
220-
221-
if let Some(FileHandle::File { file, writable }) = this.machine.file_handler.handles.remove(&fd) {
204+
if let Some(FileHandle { file, writable }) = this.machine.file_handler.handles.remove(&fd) {
222205
// We sync the file if it was opened in a mode different than read-only.
223206
if writable {
224207
// `File::sync_all` does the checks that are done when closing a file. We do this to
@@ -267,7 +250,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
267250
// host's and target's `isize`. This saves us from having to handle overflows later.
268251
let count = count.min(this.isize_max() as u64).min(isize::max_value() as u64);
269252

270-
if let Some(FileHandle::File { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
253+
if let Some(FileHandle { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
271254
// This can never fail because `count` was capped to be smaller than
272255
// `isize::max_value()`.
273256
let count = isize::try_from(count).unwrap();
@@ -321,7 +304,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
321304
// host's and target's `isize`. This saves us from having to handle overflows later.
322305
let count = count.min(this.isize_max() as u64).min(isize::max_value() as u64);
323306

324-
if let Some(FileHandle::File { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
307+
if let Some(FileHandle { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
325308
let bytes = this.memory.read_bytes(buf, Size::from_bytes(count))?;
326309
let result = file.write(&bytes).map(|c| i64::try_from(c).unwrap());
327310
this.try_unwrap_io_result(result)
@@ -356,7 +339,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
356339
return Ok(-1);
357340
};
358341

359-
if let Some(FileHandle::File { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
342+
if let Some(FileHandle { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
360343
let result = file.seek(seek_from).map(|offset| offset as i64);
361344
this.try_unwrap_io_result(result)
362345
} else {
@@ -719,8 +702,8 @@ impl FileMetadata {
719702
) -> InterpResult<'tcx, Option<FileMetadata>> {
720703
let option = ecx.machine.file_handler.handles.get(&fd);
721704
let file = match option {
722-
Some(FileHandle::File { file, writable: _ }) => file,
723-
Some(_) | None => return ecx.handle_not_found().map(|_: i32| None),
705+
Some(FileHandle { file, writable: _ }) => file,
706+
None => return ecx.handle_not_found().map(|_: i32| None),
724707
};
725708
let metadata = file.metadata();
726709

0 commit comments

Comments
 (0)