Skip to content

Commit 1981895

Browse files
committed
Auto merge of #3444 - RalfJung:linux-epoll-eventfd-cleanup, r=RalfJung
shims/linux: move epoll and eventfd into their own respective files Also put the FD types into those files; they can then even be made private there.
2 parents 9c50278 + 2cfb3a6 commit 1981895

File tree

7 files changed

+105
-106
lines changed

7 files changed

+105
-106
lines changed

src/tools/miri/src/shims/unix/fd.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ pub trait FileDescriptor: std::fmt::Debug + Any {
5252
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>>;
5353

5454
fn is_tty(&self, _communicate_allowed: bool) -> bool {
55+
// Most FDs are not tty's and the consequence of a wrong `false` are minor,
56+
// so we use a default impl here.
5557
false
5658
}
5759
}

src/tools/miri/src/shims/unix/linux/fd.rs renamed to src/tools/miri/src/shims/unix/linux/epoll.rs

Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,50 @@
1-
use std::cell::Cell;
1+
use std::io;
2+
3+
use rustc_data_structures::fx::FxHashMap;
24

35
use crate::shims::unix::*;
46
use crate::*;
5-
use epoll::{Epoll, EpollEvent};
6-
use event::Event;
77

8-
pub mod epoll;
9-
pub mod event;
8+
/// An `Epoll` file descriptor connects file handles and epoll events
9+
#[derive(Clone, Debug, Default)]
10+
struct Epoll {
11+
/// The file descriptors we are watching, and what we are watching for.
12+
file_descriptors: FxHashMap<i32, EpollEvent>,
13+
}
14+
15+
/// Epoll Events associate events with data.
16+
/// These fields are currently unused by miri.
17+
/// This matches the `epoll_event` struct defined
18+
/// by the epoll_ctl man page. For more information
19+
/// see the man page:
20+
///
21+
/// <https://man7.org/linux/man-pages/man2/epoll_ctl.2.html>
22+
#[derive(Clone, Debug)]
23+
struct EpollEvent {
24+
#[allow(dead_code)]
25+
events: u32,
26+
/// `Scalar<Provenance>` is used to represent the
27+
/// `epoll_data` type union.
28+
#[allow(dead_code)]
29+
data: Scalar<Provenance>,
30+
}
31+
32+
impl FileDescriptor for Epoll {
33+
fn name(&self) -> &'static str {
34+
"epoll"
35+
}
36+
37+
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
38+
Ok(Box::new(self.clone()))
39+
}
40+
41+
fn close<'tcx>(
42+
self: Box<Self>,
43+
_communicate_allowed: bool,
44+
) -> InterpResult<'tcx, io::Result<i32>> {
45+
Ok(Ok(0))
46+
}
47+
}
1048

1149
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
1250
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
@@ -156,49 +194,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
156194
Ok(Scalar::from_i32(this.fd_not_found()?))
157195
}
158196
}
159-
160-
/// This function creates an `Event` that is used as an event wait/notify mechanism by
161-
/// user-space applications, and by the kernel to notify user-space applications of events.
162-
/// The `Event` contains an `u64` counter maintained by the kernel. The counter is initialized
163-
/// with the value specified in the `initval` argument.
164-
///
165-
/// A new file descriptor referring to the `Event` is returned. The `read`, `write`, `poll`,
166-
/// `select`, and `close` operations can be performed on the file descriptor. For more
167-
/// information on these operations, see the man page linked below.
168-
///
169-
/// The `flags` are not currently implemented for eventfd.
170-
/// The `flags` may be bitwise ORed to change the behavior of `eventfd`:
171-
/// `EFD_CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor.
172-
/// `EFD_NONBLOCK` - Set the `O_NONBLOCK` file status flag on the new open file description.
173-
/// `EFD_SEMAPHORE` - miri does not support semaphore-like semantics.
174-
///
175-
/// <https://linux.die.net/man/2/eventfd>
176-
#[expect(clippy::needless_if)]
177-
fn eventfd(
178-
&mut self,
179-
val: &OpTy<'tcx, Provenance>,
180-
flags: &OpTy<'tcx, Provenance>,
181-
) -> InterpResult<'tcx, Scalar<Provenance>> {
182-
let this = self.eval_context_mut();
183-
184-
let val = this.read_scalar(val)?.to_u32()?;
185-
let flags = this.read_scalar(flags)?.to_i32()?;
186-
187-
let efd_cloexec = this.eval_libc_i32("EFD_CLOEXEC");
188-
let efd_nonblock = this.eval_libc_i32("EFD_NONBLOCK");
189-
let efd_semaphore = this.eval_libc_i32("EFD_SEMAPHORE");
190-
191-
if flags & (efd_cloexec | efd_nonblock | efd_semaphore) == 0 {
192-
throw_unsup_format!("{flags} is unsupported");
193-
}
194-
// FIXME handle the cloexec and nonblock flags
195-
if flags & efd_cloexec == efd_cloexec {}
196-
if flags & efd_nonblock == efd_nonblock {}
197-
if flags & efd_semaphore == efd_semaphore {
198-
throw_unsup_format!("EFD_SEMAPHORE is unsupported");
199-
}
200-
201-
let fd = this.machine.fds.insert_fd(Box::new(Event { val: Cell::new(val.into()) }));
202-
Ok(Scalar::from_i32(fd))
203-
}
204197
}

src/tools/miri/src/shims/unix/linux/fd/event.rs renamed to src/tools/miri/src/shims/unix/linux/eventfd.rs

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
use crate::shims::unix::FileDescriptor;
1+
//! Linux `eventfd` implementation.
2+
//! Currently just a stub.
3+
use std::cell::Cell;
4+
use std::io;
25

3-
use rustc_const_eval::interpret::InterpResult;
46
use rustc_middle::ty::TyCtxt;
57
use rustc_target::abi::Endian;
68

7-
use std::cell::Cell;
8-
use std::io;
9+
use crate::shims::unix::*;
10+
use crate::*;
911

1012
/// A kind of file descriptor created by `eventfd`.
1113
/// The `Event` type isn't currently written to by `eventfd`.
@@ -15,10 +17,10 @@ use std::io;
1517
///
1618
/// <https://man.netbsd.org/eventfd.2>
1719
#[derive(Debug)]
18-
pub struct Event {
20+
struct Event {
1921
/// The object contains an unsigned 64-bit integer (uint64_t) counter that is maintained by the
2022
/// kernel. This counter is initialized with the value specified in the argument initval.
21-
pub val: Cell<u64>,
23+
val: Cell<u64>,
2224
}
2325

2426
impl FileDescriptor for Event {
@@ -70,3 +72,51 @@ impl FileDescriptor for Event {
7072
Ok(Ok(8))
7173
}
7274
}
75+
76+
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
77+
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
78+
/// This function creates an `Event` that is used as an event wait/notify mechanism by
79+
/// user-space applications, and by the kernel to notify user-space applications of events.
80+
/// The `Event` contains an `u64` counter maintained by the kernel. The counter is initialized
81+
/// with the value specified in the `initval` argument.
82+
///
83+
/// A new file descriptor referring to the `Event` is returned. The `read`, `write`, `poll`,
84+
/// `select`, and `close` operations can be performed on the file descriptor. For more
85+
/// information on these operations, see the man page linked below.
86+
///
87+
/// The `flags` are not currently implemented for eventfd.
88+
/// The `flags` may be bitwise ORed to change the behavior of `eventfd`:
89+
/// `EFD_CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor.
90+
/// `EFD_NONBLOCK` - Set the `O_NONBLOCK` file status flag on the new open file description.
91+
/// `EFD_SEMAPHORE` - miri does not support semaphore-like semantics.
92+
///
93+
/// <https://linux.die.net/man/2/eventfd>
94+
#[expect(clippy::needless_if)]
95+
fn eventfd(
96+
&mut self,
97+
val: &OpTy<'tcx, Provenance>,
98+
flags: &OpTy<'tcx, Provenance>,
99+
) -> InterpResult<'tcx, Scalar<Provenance>> {
100+
let this = self.eval_context_mut();
101+
102+
let val = this.read_scalar(val)?.to_u32()?;
103+
let flags = this.read_scalar(flags)?.to_i32()?;
104+
105+
let efd_cloexec = this.eval_libc_i32("EFD_CLOEXEC");
106+
let efd_nonblock = this.eval_libc_i32("EFD_NONBLOCK");
107+
let efd_semaphore = this.eval_libc_i32("EFD_SEMAPHORE");
108+
109+
if flags & (efd_cloexec | efd_nonblock | efd_semaphore) == 0 {
110+
throw_unsup_format!("{flags} is unsupported");
111+
}
112+
// FIXME handle the cloexec and nonblock flags
113+
if flags & efd_cloexec == efd_cloexec {}
114+
if flags & efd_nonblock == efd_nonblock {}
115+
if flags & efd_semaphore == efd_semaphore {
116+
throw_unsup_format!("EFD_SEMAPHORE is unsupported");
117+
}
118+
119+
let fd = this.machine.fds.insert_fd(Box::new(Event { val: Cell::new(val.into()) }));
120+
Ok(Scalar::from_i32(fd))
121+
}
122+
}

src/tools/miri/src/shims/unix/linux/fd/epoll.rs

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/tools/miri/src/shims/unix/linux/foreign_items.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use crate::machine::SIGRTMIN;
66
use crate::shims::unix::*;
77
use crate::*;
88
use shims::foreign_items::EmulateForeignItemResult;
9-
use shims::unix::linux::fd::EvalContextExt as _;
9+
use shims::unix::linux::epoll::EvalContextExt as _;
10+
use shims::unix::linux::eventfd::EvalContextExt as _;
1011
use shims::unix::linux::mem::EvalContextExt as _;
1112
use shims::unix::linux::sync::futex;
1213

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
pub mod fd;
1+
pub mod epoll;
2+
pub mod eventfd;
23
pub mod foreign_items;
34
pub mod mem;
45
pub mod sync;

src/tools/miri/src/shims/unix/socket.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use crate::*;
66
/// Pair of connected sockets.
77
///
88
/// We currently don't allow sending any data through this pair, so this can be just a dummy.
9-
/// FIXME: show proper errors when trying to send/receive
109
#[derive(Debug)]
1110
struct SocketPair;
1211

0 commit comments

Comments
 (0)