Skip to content

Commit 61b4ffc

Browse files
roypatShadowCurse
authored andcommitted
io: implement [Read|Write]Volatile for &File and co
Implement these traits for references to types that implement them, e.g. &File, &TcpStream, &UnixStream, &Stdout, etc. This mirrors the standard library implementations and allows calling read/write methods from contexts where no mutable reference is available. Signed-off-by: Patrick Roy <[email protected]>
1 parent 675796e commit 61b4ffc

File tree

2 files changed

+66
-16
lines changed

2 files changed

+66
-16
lines changed

coverage_config_x86_64.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"coverage_score": 92.92,
2+
"coverage_score": 92.28,
33
"exclude_path": "mmap_windows.rs",
44
"crate_features": "backend-mmap,backend-atomic,backend-bitmap"
55
}

src/io.rs

Lines changed: 65 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::io::{Cursor, ErrorKind};
1212
use std::io::Stdout;
1313

1414
#[cfg(feature = "rawfd")]
15-
use std::os::fd::AsRawFd;
15+
use std::os::fd::{AsFd, AsRawFd, BorrowedFd};
1616

1717
macro_rules! retry_eintr {
1818
($io_call: expr) => {
@@ -127,7 +127,7 @@ pub trait WriteVolatile {
127127
// We explicitly implement our traits for [`std::fs::File`] and [`std::os::unix::net::UnixStream`]
128128
// instead of providing blanket implementation for [`AsRawFd`] due to trait coherence limitations: A
129129
// blanket implementation would prevent us from providing implementations for `&mut [u8]` below, as
130-
// "an upstream crate could implement AsRawFd for &mut [u8]`.
130+
// "an upstream crate could implement AsRawFd for &mut [u8]".
131131

132132
macro_rules! impl_read_write_volatile_for_raw_fd {
133133
($raw_fd_ty:ty) => {
@@ -137,7 +137,27 @@ macro_rules! impl_read_write_volatile_for_raw_fd {
137137
&mut self,
138138
buf: &mut VolatileSlice<B>,
139139
) -> Result<usize, VolatileMemoryError> {
140-
read_volatile_raw_fd(self, buf)
140+
read_volatile_raw_fd(self.as_fd(), buf)
141+
}
142+
}
143+
144+
#[cfg(feature = "rawfd")]
145+
impl ReadVolatile for &$raw_fd_ty {
146+
fn read_volatile<B: BitmapSlice>(
147+
&mut self,
148+
buf: &mut VolatileSlice<B>,
149+
) -> Result<usize, VolatileMemoryError> {
150+
read_volatile_raw_fd(self.as_fd(), buf)
151+
}
152+
}
153+
154+
#[cfg(feature = "rawfd")]
155+
impl ReadVolatile for &mut $raw_fd_ty {
156+
fn read_volatile<B: BitmapSlice>(
157+
&mut self,
158+
buf: &mut VolatileSlice<B>,
159+
) -> Result<usize, VolatileMemoryError> {
160+
read_volatile_raw_fd(self.as_fd(), buf)
141161
}
142162
}
143163

@@ -147,7 +167,27 @@ macro_rules! impl_read_write_volatile_for_raw_fd {
147167
&mut self,
148168
buf: &VolatileSlice<B>,
149169
) -> Result<usize, VolatileMemoryError> {
150-
write_volatile_raw_fd(self, buf)
170+
write_volatile_raw_fd(self.as_fd(), buf)
171+
}
172+
}
173+
174+
#[cfg(feature = "rawfd")]
175+
impl WriteVolatile for &$raw_fd_ty {
176+
fn write_volatile<B: BitmapSlice>(
177+
&mut self,
178+
buf: &VolatileSlice<B>,
179+
) -> Result<usize, VolatileMemoryError> {
180+
write_volatile_raw_fd(self.as_fd(), buf)
181+
}
182+
}
183+
184+
#[cfg(feature = "rawfd")]
185+
impl WriteVolatile for &mut $raw_fd_ty {
186+
fn write_volatile<B: BitmapSlice>(
187+
&mut self,
188+
buf: &VolatileSlice<B>,
189+
) -> Result<usize, VolatileMemoryError> {
190+
write_volatile_raw_fd(self.as_fd(), buf)
151191
}
152192
}
153193
};
@@ -159,7 +199,17 @@ impl WriteVolatile for Stdout {
159199
&mut self,
160200
buf: &VolatileSlice<B>,
161201
) -> Result<usize, VolatileMemoryError> {
162-
write_volatile_raw_fd(self, buf)
202+
write_volatile_raw_fd(self.as_fd(), buf)
203+
}
204+
}
205+
206+
#[cfg(feature = "rawfd")]
207+
impl WriteVolatile for &Stdout {
208+
fn write_volatile<B: BitmapSlice>(
209+
&mut self,
210+
buf: &VolatileSlice<B>,
211+
) -> Result<usize, VolatileMemoryError> {
212+
write_volatile_raw_fd(self.as_fd(), buf)
163213
}
164214
}
165215

@@ -174,18 +224,18 @@ impl_read_write_volatile_for_raw_fd!(std::os::fd::BorrowedFd<'_>);
174224
///
175225
/// Returns the numbers of bytes read.
176226
#[cfg(feature = "rawfd")]
177-
fn read_volatile_raw_fd<Fd: AsRawFd>(
178-
raw_fd: &mut Fd,
227+
fn read_volatile_raw_fd(
228+
raw_fd: BorrowedFd<'_>,
179229
buf: &mut VolatileSlice<impl BitmapSlice>,
180230
) -> Result<usize, VolatileMemoryError> {
181231
let fd = raw_fd.as_raw_fd();
182232
let guard = buf.ptr_guard_mut();
183233

184234
let dst = guard.as_ptr().cast::<libc::c_void>();
185235

186-
// SAFETY: We got a valid file descriptor from `AsRawFd`. The memory pointed to by `dst` is
187-
// valid for writes of length `buf.len() by the invariants upheld by the constructor
188-
// of `VolatileSlice`.
236+
// SAFETY: Rust's I/O safety invariants ensure that BorrowedFd contains a valid file descriptor`.
237+
// The memory pointed to by `dst` is valid for writes of length `buf.len() by the invariants
238+
// upheld by the constructor of `VolatileSlice`.
189239
let bytes_read = unsafe { libc::read(fd, dst, buf.len()) };
190240

191241
if bytes_read < 0 {
@@ -205,18 +255,18 @@ fn read_volatile_raw_fd<Fd: AsRawFd>(
205255
///
206256
/// Returns the numbers of bytes written.
207257
#[cfg(feature = "rawfd")]
208-
fn write_volatile_raw_fd<Fd: AsRawFd>(
209-
raw_fd: &mut Fd,
258+
fn write_volatile_raw_fd(
259+
raw_fd: BorrowedFd<'_>,
210260
buf: &VolatileSlice<impl BitmapSlice>,
211261
) -> Result<usize, VolatileMemoryError> {
212262
let fd = raw_fd.as_raw_fd();
213263
let guard = buf.ptr_guard();
214264

215265
let src = guard.as_ptr().cast::<libc::c_void>();
216266

217-
// SAFETY: We got a valid file descriptor from `AsRawFd`. The memory pointed to by `src` is
218-
// valid for reads of length `buf.len() by the invariants upheld by the constructor
219-
// of `VolatileSlice`.
267+
// SAFETY: Rust's I/O safety invariants ensure that BorrowedFd contains a valid file descriptor`.
268+
// The memory pointed to by `src` is valid for reads of length `buf.len() by the invariants
269+
// upheld by the constructor of `VolatileSlice`.
220270
let bytes_written = unsafe { libc::write(fd, src, buf.len()) };
221271

222272
if bytes_written < 0 {

0 commit comments

Comments
 (0)