diff --git a/src/shims/unix/fs.rs b/src/shims/unix/fs.rs index 2044ded420..66bf98228f 100644 --- a/src/shims/unix/fs.rs +++ b/src/shims/unix/fs.rs @@ -31,6 +31,10 @@ struct FileHandle { trait FileDescriptor: std::fmt::Debug { fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle>; + fn as_epoll_handle<'tcx>(&mut self) -> InterpResult<'tcx, &mut Epoll> { + throw_unsup_format!("not an epoll file descriptor"); + } + fn read<'tcx>( &mut self, communicate_allowed: bool, @@ -774,13 +778,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } let fh = &mut this.machine.file_handler; - let fd = fh.insert_fd(Box::new(Epoll)); + let fd = fh.insert_fd(Box::new(Epoll::default())); Ok(fd) } fn epoll_ctl( &mut self, - _epfd: &OpTy<'tcx, Provenance>, + epfd: &OpTy<'tcx, Provenance>, op: &OpTy<'tcx, Provenance>, fd: &OpTy<'tcx, Provenance>, _event: &OpTy<'tcx, Provenance>, @@ -788,6 +792,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let this = self.eval_context_mut(); let values = this.read_scalar(op)?.to_i32()?; + let epfd = this.read_scalar(epfd)?.to_i32()?; let fd = this.read_scalar(fd)?.to_i32()?; let epoll_ctl_add = this.eval_libc_i32("EPOLL_CTL_ADD")?; @@ -795,8 +800,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let epoll_ctl_del = this.eval_libc_i32("EPOLL_CTL_DEL")?; if values == epoll_ctl_add { - if let Some(_file_descriptor) = this.machine.file_handler.handles.get(&fd) { - Ok(-1) + if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) { + let epfd = epfd.as_epoll_handle()?; + epfd.file_descriptors.insert(fd, ()); + Ok(0) } else { this.handle_not_found() } diff --git a/src/shims/unix/fs/epoll.rs b/src/shims/unix/fs/epoll.rs index 1d01c1af01..6986791326 100644 --- a/src/shims/unix/fs/epoll.rs +++ b/src/shims/unix/fs/epoll.rs @@ -5,17 +5,24 @@ use crate::*; use super::FileDescriptor; use super::FileHandle; +use std::collections::HashMap; use std::io; use std::io::SeekFrom; -#[derive(Debug)] -pub struct Epoll; +#[derive(Clone, Debug, Default)] +pub struct Epoll { + pub file_descriptors: HashMap, +} impl FileDescriptor for Epoll { fn as_file_handle<'tcx>(&self) -> InterpResult<'tcx, &FileHandle> { throw_unsup_format!("epoll file descriptors cannot be used as FileHandle"); } + fn as_epoll_handle<'tcx>(&mut self) -> InterpResult<'tcx, &mut Epoll> { + Ok(self) + } + fn read<'tcx>( &mut self, _communicate_allowed: bool, @@ -48,7 +55,7 @@ impl FileDescriptor for Epoll { } fn dup<'tcx>(&mut self) -> io::Result> { - Ok(Box::new(Epoll)) + Ok(Box::new(self.clone())) } fn as_unix_host_fd(&self) -> Option { diff --git a/tests/fail/crates/tokio_mvp.rs b/tests/fail/crates/tokio_mvp.rs index 995090c862..1fac1aa1bb 100644 --- a/tests/fail/crates/tokio_mvp.rs +++ b/tests/fail/crates/tokio_mvp.rs @@ -1,5 +1,5 @@ //@compile-flags: -Zmiri-disable-isolation -//@error-pattern: unsupported operation: event file descriptors cannot be closed +//@error-pattern: unsupported operation: can't call foreign function: socketpair //@normalize-stderr-test: " = note: inside .*\n" -> "" //@only-target-linux: the errors differ too much between platforms diff --git a/tests/fail/crates/tokio_mvp.stderr b/tests/fail/crates/tokio_mvp.stderr index 4bc8a1145f..f44a7602bc 100644 --- a/tests/fail/crates/tokio_mvp.stderr +++ b/tests/fail/crates/tokio_mvp.stderr @@ -1,8 +1,8 @@ -error: unsupported operation: event file descriptors cannot be closed - --> RUSTLIB/std/src/os/fd/owned.rs:LL:CC +error: unsupported operation: can't call foreign function: socketpair + --> CARGO_REGISTRY/.../mod.rs:LL:CC | -LL | let _ = libc::close(self.fd); - | ^^^^^^^^^^^^^^^^^^^^ event file descriptors cannot be closed +LL | syscall!(socketpair(libc::AF_UNIX, flags, 0, fds.as_mut_ptr()))?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function: socketpair | = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support = note: backtrace: @@ -11,7 +11,7 @@ note: inside `main` at $DIR/tokio_mvp.rs:LL:CC | LL | #[tokio::main] | ^^^^^^^^^^^^^^ - = note: this error originates in the attribute macro `tokio::main` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `syscall` which comes from the expansion of the attribute macro `tokio::main` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace