Skip to content

Commit 332c9a0

Browse files
authored
Remove is_read_write from rustix. (#1279)
Remove `is_read_write` and `is_file_read_write` from rustix. These are higher-level functionality that can be implemented on top of rustix.
1 parent 99404fc commit 332c9a0

7 files changed

Lines changed: 4 additions & 166 deletions

File tree

src/backend/libc/io/syscalls.rs

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ use crate::io::ReadWriteFlags;
1818
use crate::io::{self, FdFlags};
1919
use crate::ioctl::{IoctlOutput, RawOpcode};
2020
use core::cmp::min;
21-
#[cfg(all(feature = "fs", feature = "net"))]
22-
use libc_errno::errno;
2321
#[cfg(not(any(target_os = "espidf", target_os = "horizon")))]
2422
use {
2523
crate::backend::MAX_IOV,
@@ -224,60 +222,6 @@ pub(crate) unsafe fn ioctl_readonly(
224222
ioctl(fd, request, arg)
225223
}
226224

227-
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
228-
#[cfg(all(feature = "fs", feature = "net"))]
229-
pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
230-
use core::mem::MaybeUninit;
231-
232-
let (mut read, mut write) = crate::fs::fd::_is_file_read_write(fd)?;
233-
let mut not_socket = false;
234-
if read {
235-
// Do a `recv` with `PEEK` and `DONTWAIT` for 1 byte. A 0 indicates
236-
// the read side is shut down; an `EWOULDBLOCK` indicates the read
237-
// side is still open.
238-
match unsafe {
239-
c::recv(
240-
borrowed_fd(fd),
241-
MaybeUninit::<[u8; 1]>::uninit()
242-
.as_mut_ptr()
243-
.cast::<c::c_void>(),
244-
1,
245-
c::MSG_PEEK | c::MSG_DONTWAIT,
246-
)
247-
} {
248-
0 => read = false,
249-
-1 => {
250-
#[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK`
251-
match errno().0 {
252-
c::EAGAIN | c::EWOULDBLOCK => (),
253-
c::ENOTSOCK => not_socket = true,
254-
err => return Err(io::Errno(err)),
255-
}
256-
}
257-
_ => (),
258-
}
259-
}
260-
if write && !not_socket {
261-
// Do a `send` with `DONTWAIT` for 0 bytes. An `EPIPE` indicates
262-
// the write side is shut down.
263-
if unsafe { c::send(borrowed_fd(fd), [].as_ptr(), 0, c::MSG_DONTWAIT) } == -1 {
264-
#[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK`
265-
match errno().0 {
266-
c::EAGAIN | c::EWOULDBLOCK | c::ENOTSOCK => (),
267-
c::EPIPE => write = false,
268-
err => return Err(io::Errno(err)),
269-
}
270-
}
271-
}
272-
Ok((read, write))
273-
}
274-
275-
#[cfg(target_os = "wasi")]
276-
#[cfg(all(feature = "fs", feature = "net"))]
277-
pub(crate) fn is_read_write(_fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
278-
todo!("Implement is_read_write for WASI in terms of fd_fdstat_get");
279-
}
280-
281225
pub(crate) fn fcntl_getfd(fd: BorrowedFd<'_>) -> io::Result<FdFlags> {
282226
let flags = unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETFD))? };
283227
Ok(FdFlags::from_bits_retain(bitcast!(flags)))

src/backend/linux_raw/io/syscalls.rs

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ use crate::backend::{c, MAX_IOV};
2323
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
2424
use crate::io::{self, DupFlags, FdFlags, IoSlice, IoSliceMut, ReadWriteFlags};
2525
use crate::ioctl::{IoctlOutput, RawOpcode};
26-
#[cfg(all(feature = "fs", feature = "net"))]
27-
use crate::net::{RecvFlags, SendFlags};
2826
use core::cmp;
2927
use linux_raw_sys::general::{F_DUPFD_CLOEXEC, F_GETFD, F_SETFD};
3028

@@ -265,49 +263,6 @@ pub(crate) unsafe fn ioctl_readonly(
265263
ret_c_int(syscall_readonly!(__NR_ioctl, fd, c_uint(request), arg))
266264
}
267265

268-
#[cfg(all(feature = "fs", feature = "net"))]
269-
pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
270-
let (mut read, mut write) = crate::fs::fd::_is_file_read_write(fd)?;
271-
let mut not_socket = false;
272-
if read {
273-
// Do a `recv` with `PEEK` and `DONTWAIT` for 1 byte. A 0 indicates
274-
// the read side is shut down; an `EWOULDBLOCK` indicates the read
275-
// side is still open.
276-
let mut buf = [core::mem::MaybeUninit::<u8>::uninit()];
277-
match unsafe {
278-
crate::backend::net::syscalls::recv(
279-
fd,
280-
buf.as_mut_ptr().cast::<u8>(),
281-
1,
282-
RecvFlags::PEEK | RecvFlags::DONTWAIT,
283-
)
284-
} {
285-
Ok(0) => read = false,
286-
Err(err) => {
287-
#[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK`
288-
match err {
289-
io::Errno::AGAIN | io::Errno::WOULDBLOCK => (),
290-
io::Errno::NOTSOCK => not_socket = true,
291-
_ => return Err(err),
292-
}
293-
}
294-
Ok(_) => (),
295-
}
296-
}
297-
if write && !not_socket {
298-
// Do a `send` with `DONTWAIT` for 0 bytes. An `EPIPE` indicates
299-
// the write side is shut down.
300-
#[allow(unreachable_patterns)] // `EAGAIN` equals `EWOULDBLOCK`
301-
match crate::backend::net::syscalls::send(fd, &[], SendFlags::DONTWAIT) {
302-
Err(io::Errno::AGAIN | io::Errno::WOULDBLOCK | io::Errno::NOTSOCK) => (),
303-
Err(io::Errno::PIPE) => write = false,
304-
Err(err) => return Err(err),
305-
Ok(_) => (),
306-
}
307-
}
308-
Ok((read, write))
309-
}
310-
311266
#[inline]
312267
pub(crate) fn dup(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> {
313268
unsafe { ret_owned_fd(syscall_readonly!(__NR_dup, fd)) }

src/fs/fd.rs

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
use crate::fs::Mode;
55
#[cfg(not(target_os = "wasi"))]
66
use crate::fs::{Gid, Uid};
7-
use crate::fs::{OFlags, SeekFrom, Timespec};
7+
use crate::fs::{SeekFrom, Timespec};
88
use crate::{backend, io};
9-
use backend::fd::{AsFd, BorrowedFd};
9+
use backend::fd::AsFd;
1010
#[cfg(not(any(
1111
netbsdlike,
1212
target_os = "dragonfly",
@@ -127,6 +127,7 @@ pub fn tell<Fd: AsFd>(fd: Fd) -> io::Result<u64> {
127127
///
128128
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fchmod.html
129129
/// [Linux]: https://man7.org/linux/man-pages/man2/fchmod.2.html
130+
/// [`OFlags::PATH`]: crate::fs::OFlags::PATH
130131
#[cfg(not(target_os = "wasi"))]
131132
#[inline]
132133
pub fn fchmod<Fd: AsFd>(fd: Fd, mode: Mode) -> io::Result<()> {
@@ -252,36 +253,6 @@ pub fn fallocate<Fd: AsFd>(fd: Fd, mode: FallocateFlags, offset: u64, len: u64)
252253
backend::fs::syscalls::fallocate(fd.as_fd(), mode, offset, len)
253254
}
254255

255-
/// `fcntl(fd, F_GETFL) & O_ACCMODE`
256-
///
257-
/// Returns a pair of booleans indicating whether the file descriptor is
258-
/// readable and/or writable, respectively. This is only reliable on files; for
259-
/// example, it doesn't reflect whether sockets have been shut down; for
260-
/// general I/O handle support, use [`io::is_read_write`].
261-
#[inline]
262-
pub fn is_file_read_write<Fd: AsFd>(fd: Fd) -> io::Result<(bool, bool)> {
263-
_is_file_read_write(fd.as_fd())
264-
}
265-
266-
pub(crate) fn _is_file_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
267-
let mode = backend::fs::syscalls::fcntl_getfl(fd)?;
268-
269-
// Check for `O_PATH`.
270-
#[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))]
271-
if mode.contains(OFlags::PATH) {
272-
return Ok((false, false));
273-
}
274-
275-
// Use `RWMODE` rather than `ACCMODE` as `ACCMODE` may include `O_PATH`.
276-
// We handled `O_PATH` above.
277-
match mode & OFlags::RWMODE {
278-
OFlags::RDONLY => Ok((true, false)),
279-
OFlags::RDWR => Ok((true, true)),
280-
OFlags::WRONLY => Ok((false, true)),
281-
_ => unreachable!(),
282-
}
283-
}
284-
285256
/// `fsync(fd)`—Ensures that file data and metadata is written to the
286257
/// underlying storage device.
287258
///

src/io/is_read_write.rs

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

src/io/mod.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ mod errno;
1212
#[cfg(not(windows))]
1313
mod fcntl;
1414
mod ioctl;
15-
#[cfg(not(any(windows, target_os = "redox")))]
16-
#[cfg(all(feature = "fs", feature = "net"))]
17-
mod is_read_write;
1815
#[cfg(not(windows))]
1916
mod read_write;
2017

@@ -25,8 +22,5 @@ pub use errno::{retry_on_intr, Errno, Result};
2522
#[cfg(not(windows))]
2623
pub use fcntl::*;
2724
pub use ioctl::*;
28-
#[cfg(not(any(windows, target_os = "redox")))]
29-
#[cfg(all(feature = "fs", feature = "net"))]
30-
pub use is_read_write::*;
3125
#[cfg(not(windows))]
3226
pub use read_write::*;

tests/fs/file.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,6 @@ fn test_file() {
148148
assert!(statvfs.f_frsize > 0);
149149
}
150150

151-
#[cfg(all(feature = "fs", feature = "net"))]
152-
assert_eq!(rustix::io::is_read_write(&file).unwrap(), (true, false));
153-
154151
assert_ne!(rustix::io::ioctl_fionread(&file).unwrap(), 0);
155152
}
156153

tests/io/ioctl.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
// `is_read_write` is not yet implemented on Windows. And `ioctl_fionread`
2-
// on Windows doesn't work on files.
1+
// `ioctl_fionread` on Windows doesn't work on files.
32
#[cfg(not(windows))]
43
#[test]
54
fn test_ioctls() {
65
let file = std::fs::File::open("Cargo.toml").unwrap();
76

8-
#[cfg(all(feature = "fs", feature = "net"))]
9-
assert_eq!(rustix::io::is_read_write(&file).unwrap(), (true, false));
10-
117
assert_eq!(
128
rustix::io::ioctl_fionread(&file).unwrap(),
139
file.metadata().unwrap().len()

0 commit comments

Comments
 (0)