Skip to content

Commit 41f42d6

Browse files
committed
Sync rustix with Windows Unix ioctls.
Define `FIONREAD` on Windows.
1 parent 3a2f309 commit 41f42d6

File tree

7 files changed

+35
-4
lines changed

7 files changed

+35
-4
lines changed

src/imp/libc/io/windows_syscalls.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,20 @@ use crate::fd::{BorrowedFd, RawFd};
77
use crate::io;
88
use crate::io::PollFd;
99
use core::convert::TryInto;
10+
use core::mem::MaybeUninit;
1011

1112
pub(crate) unsafe fn close(raw_fd: RawFd) {
1213
let _ = c::close(raw_fd as LibcFd);
1314
}
1415

16+
pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result<u64> {
17+
let mut nread = MaybeUninit::<c::c_ulong>::uninit();
18+
unsafe {
19+
ret(c::ioctl(borrowed_fd(fd), c::FIONREAD, nread.as_mut_ptr()))?;
20+
Ok(u64::from(nread.assume_init()))
21+
}
22+
}
23+
1524
pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> {
1625
unsafe {
1726
let mut data = value as c::c_uint;

src/imp/libc/winsock_c.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use windows_sys::Win32::Networking::WinSock;
77

88
pub(crate) use libc::{
99
c_char, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint, c_ulong, c_ulonglong,
10-
c_ushort, ssize_t,
10+
c_ushort, c_void, ssize_t,
1111
};
1212
pub(crate) type socklen_t = i32;
1313

src/io/ioctl.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub fn ioctl_fioclex<Fd: AsFd>(fd: Fd) -> io::Result<()> {
5757
/// - [Winsock2]
5858
///
5959
/// [Linux]: https://man7.org/linux/man-pages/man2/ioctl.2.html
60-
/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-ioctlsocket
60+
/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes
6161
#[inline]
6262
#[doc(alias = "FIONBIO")]
6363
pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
@@ -71,9 +71,11 @@ pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
7171
///
7272
/// # References
7373
/// - [Linux]
74+
/// - [Winsock2]
7475
///
7576
/// [Linux]: https://man7.org/linux/man-pages/man2/ioctl_tty.2.html
76-
#[cfg(not(any(windows, target_os = "redox")))]
77+
/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes
78+
#[cfg(not(target_os = "redox"))]
7779
#[inline]
7880
#[doc(alias = "FIONREAD")]
7981
pub fn ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64> {

src/io/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub use eventfd::{eventfd, EventfdFlags};
3636
#[cfg(any(target_os = "ios", target_os = "macos"))]
3737
pub use ioctl::ioctl_fioclex;
3838
pub use ioctl::ioctl_fionbio;
39-
#[cfg(not(any(windows, target_os = "redox")))]
39+
#[cfg(not(target_os = "redox"))]
4040
pub use ioctl::ioctl_fionread;
4141
#[cfg(any(target_os = "android", target_os = "linux"))]
4242
pub use ioctl::{ioctl_blkpbszget, ioctl_blksszget};

tests/io/ioctl.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// `is_read_write` is not yet implemented on Windows. And `ioctl_fionread`
2+
// on Windows doesn't work on files.
3+
#[cfg(not(windows))]
4+
#[test]
5+
fn test_ioctls() {
6+
let file = std::fs::File::open("Cargo.toml").unwrap();
7+
8+
assert_eq!(rustix::io::is_read_write(&file).unwrap(), (true, false));
9+
10+
assert_eq!(
11+
rustix::io::ioctl_fionread(&file).unwrap(),
12+
file.metadata().unwrap().len()
13+
);
14+
}

tests/io/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ mod error;
1818
mod eventfd;
1919
#[cfg(not(windows))]
2020
mod from_into;
21+
#[cfg(not(target_os = "redox"))]
22+
mod ioctl;
2123
mod poll;
2224
#[cfg(all(feature = "procfs", any(target_os = "android", target_os = "linux")))]
2325
mod procfs;

tests/net/poll.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ fn server(ready: Arc<(Mutex<u16>, Condvar)>) {
4545
assert!(fds[0].revents().intersects(PollFlags::IN));
4646
assert!(!fds[0].revents().intersects(PollFlags::OUT));
4747

48+
let expected_nread = rustix::io::ioctl_fionread(&data_socket).unwrap();
4849
let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap();
4950
assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "hello, world");
51+
assert_eq!(expected_nread, nread as u64);
5052

5153
let mut fds = [PollFd::new(&data_socket, PollFlags::OUT)];
5254
assert_eq!(poll(&mut fds, -1).unwrap(), 1);
@@ -89,8 +91,10 @@ fn client(ready: Arc<(Mutex<u16>, Condvar)>) {
8991
assert!(fds[0].revents().intersects(PollFlags::IN));
9092
assert!(!fds[0].revents().intersects(PollFlags::OUT));
9193

94+
let expected_nread = rustix::io::ioctl_fionread(&data_socket).unwrap();
9295
let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap();
9396
assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "goodnight, moon");
97+
assert_eq!(expected_nread, nread as u64);
9498
}
9599

96100
#[test]

0 commit comments

Comments
 (0)