Skip to content

Commit 644467c

Browse files
committed
Add methods to handle invalid fides
1 parent efbe798 commit 644467c

File tree

1 file changed

+47
-26
lines changed

1 file changed

+47
-26
lines changed

src/shims/io.rs

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc::ty::layout::Size;
77
use crate::stacked_borrows::Tag;
88
use crate::*;
99

10-
struct FileHandle {
10+
pub struct FileHandle {
1111
file: File,
1212
flag: i32,
1313
}
@@ -94,12 +94,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9494
}
9595
Ok(0)
9696
} else if cmd == this.eval_libc_i32("F_GETFD")? {
97-
if let Some(handle) = this.machine.file_handler.handles.get(&fd) {
98-
Ok(handle.flag)
99-
} else {
100-
this.machine.last_error = this.eval_libc_i32("EBADF")? as u32;
101-
Ok(-1)
102-
}
97+
this.get_handle_and(fd, |handle| Ok(handle.flag), -1)
10398
} else {
10499
throw_unsup_format!("Unsupported command {:#x}", cmd);
105100
}
@@ -114,12 +109,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
114109

115110
let fd = this.read_scalar(fd_op)?.to_i32()?;
116111

117-
if let Some(handle) = this.machine.file_handler.handles.remove(&fd) {
118-
this.consume_result::<i32>(handle.file.sync_all().map(|_| 0), -1)
119-
} else {
120-
this.machine.last_error = this.eval_libc_i32("EBADF")? as u32;
121-
Ok(-1)
122-
}
112+
this.remove_handle_and(
113+
fd,
114+
|handle, this| this.consume_result::<i32>(handle.file.sync_all().map(|_| 0), -1),
115+
-1,
116+
)
123117
}
124118

125119
fn read(
@@ -141,21 +135,48 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
141135
let count = this.read_scalar(count_op)?.to_usize(&*this.tcx)?;
142136

143137
// Remove the file handle to avoid borrowing issues
144-
if let Some(mut handle) = this.machine.file_handler.handles.remove(&fd) {
145-
let bytes = handle
146-
.file
147-
.read(this.memory_mut().get_mut(buf.alloc_id)?.get_bytes_mut(
148-
tcx,
149-
buf,
150-
Size::from_bytes(count),
151-
)?)
152-
.map(|bytes| bytes as i64);
153-
// Reinsert the file handle
154-
this.machine.file_handler.handles.insert(fd, handle);
155-
this.consume_result::<i64>(bytes, -1)
138+
this.remove_handle_and(
139+
fd,
140+
|mut handle, this| {
141+
let bytes = handle
142+
.file
143+
.read(this.memory_mut().get_mut(buf.alloc_id)?.get_bytes_mut(
144+
tcx,
145+
buf,
146+
Size::from_bytes(count),
147+
)?)
148+
.map(|bytes| bytes as i64);
149+
// Reinsert the file handle
150+
this.machine.file_handler.handles.insert(fd, handle);
151+
this.consume_result::<i64>(bytes, -1)
152+
},
153+
-1,
154+
)
155+
}
156+
157+
fn get_handle_and<F, T>(&mut self, fd: i32, f: F, t: T) -> InterpResult<'tcx, T>
158+
where
159+
F: Fn(&FileHandle) -> InterpResult<'tcx, T>,
160+
{
161+
let this = self.eval_context_mut();
162+
if let Some(handle) = this.machine.file_handler.handles.get(&fd) {
163+
f(handle)
164+
} else {
165+
this.machine.last_error = this.eval_libc_i32("EBADF")? as u32;
166+
Ok(t)
167+
}
168+
}
169+
170+
fn remove_handle_and<F, T>(&mut self, fd: i32, mut f: F, t: T) -> InterpResult<'tcx, T>
171+
where
172+
F: FnMut(FileHandle, &mut MiriEvalContext<'mir, 'tcx>) -> InterpResult<'tcx, T>,
173+
{
174+
let this = self.eval_context_mut();
175+
if let Some(handle) = this.machine.file_handler.handles.remove(&fd) {
176+
f(handle, this)
156177
} else {
157178
this.machine.last_error = this.eval_libc_i32("EBADF")? as u32;
158-
Ok(-1)
179+
Ok(t)
159180
}
160181
}
161182

0 commit comments

Comments
 (0)