Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions src/shims/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::*;

/// A unique id for file descriptions. While we could use the address, considering that
/// is definitely unique, the address would expose interpreter internal state when used
/// for sorting things. So instead we generate a unique id per file description is the name
/// for sorting things. So instead we generate a unique id per file description which is the same
/// for all `dup`licates and is never reused.
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd)]
pub struct FdId(usize);
Expand Down Expand Up @@ -48,6 +48,12 @@ impl<T: ?Sized> FileDescriptionRef<T> {
pub fn id(&self) -> FdId {
self.0.id
}

/// Returns the raw address of this file description. Useful for equality comparisons.
/// Use `id` instead if this can affect user-visible behavior!
pub fn addr(&self) -> usize {
Rc::as_ptr(&self.0).addr()
}
}

/// Holds a weak reference to the actual file description.
Expand All @@ -70,6 +76,11 @@ impl<T: ?Sized> WeakFileDescriptionRef<T> {
pub fn upgrade(&self) -> Option<FileDescriptionRef<T>> {
self.0.upgrade().map(FileDescriptionRef)
}

/// Returns the raw address of this file description. Useful for equality comparisons.
pub fn addr(&self) -> usize {
self.0.as_ptr().addr()
}
}

impl<T> VisitProvenance for WeakFileDescriptionRef<T> {
Expand Down Expand Up @@ -105,12 +116,13 @@ impl<T: FileDescription + 'static> FileDescriptionExt for T {
communicate_allowed: bool,
ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<()>> {
let addr = self.addr();
match Rc::into_inner(self.0) {
Some(fd) => {
// Remove entry from the global epoll_event_interest table.
ecx.machine.epoll_interests.remove(fd.id);
// There might have been epolls interested in this FD. Remove that.
ecx.machine.epoll_interests.remove_epolls(fd.id);

fd.inner.close(communicate_allowed, ecx)
fd.inner.destroy(addr, communicate_allowed, ecx)
}
None => {
// Not the last reference.
Expand Down Expand Up @@ -183,9 +195,12 @@ pub trait FileDescription: std::fmt::Debug + FileDescriptionExt {
throw_unsup_format!("cannot seek on {}", self.name());
}

/// Close the file descriptor.
fn close<'tcx>(
/// Destroys the file description. Only called when the last duplicate file descriptor is closed.
///
/// `self_addr` is the address that this file description used to be stored at.
fn destroy<'tcx>(
self,
_self_addr: usize,
_communicate_allowed: bool,
_ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<()>>
Expand Down Expand Up @@ -362,8 +377,9 @@ impl FileDescription for FileHandle {
interp_ok((&mut &self.file).seek(offset))
}

fn close<'tcx>(
fn destroy<'tcx>(
self,
_self_addr: usize,
communicate_allowed: bool,
_ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<()>> {
Expand Down
Loading