Revision control
Copy as Markdown
Other Tools
//! The Unix `ioctl` function is effectively lots of different functions hidden
//! behind a single dynamic dispatch interface. In order to provide a type-safe
//! API, rustix makes them all separate functions so that they can have
//! dedicated static type signatures.
//!
//! Some ioctls, such as those related to filesystems, terminals, and
//! processes, live in other top-level API modules.
#![allow(unsafe_code)]
use crate::{backend, io, ioctl};
use backend::c;
use backend::fd::AsFd;
/// `ioctl(fd, FIOCLEX, NULL)`—Set the close-on-exec flag.
///
/// This is similar to `fcntl(fd, F_SETFD, FD_CLOEXEC)`, except that it avoids
/// clearing any other flags that might be set.
#[cfg(apple)]
#[inline]
#[doc(alias = "FIOCLEX")]
#[doc(alias = "FD_CLOEXEC")]
pub fn ioctl_fioclex<Fd: AsFd>(fd: Fd) -> io::Result<()> {
// SAFETY: FIOCLEX is a no-argument setter opcode.
unsafe {
let ctl = ioctl::NoArg::<ioctl::BadOpcode<{ c::FIOCLEX }>>::new();
ioctl::ioctl(fd, ctl)
}
}
/// `ioctl(fd, FIONBIO, &value)`—Enables or disables non-blocking mode.
///
/// # References
/// - [Winsock]
/// - [NetBSD]
/// - [OpenBSD]
///
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes
#[inline]
#[doc(alias = "FIONBIO")]
pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
// SAFETY: FIONBIO is a pointer setter opcode.
unsafe {
let ctl = ioctl::Setter::<ioctl::BadOpcode<{ c::FIONBIO }>, c::c_int>::new(value.into());
ioctl::ioctl(fd, ctl)
}
}
/// `ioctl(fd, FIONREAD)`—Returns the number of bytes ready to be read.
///
/// The result of this function gets silently coerced into a C `int` by the OS,
/// so it may contain a wrapped value.
///
/// # References
/// - [Linux]
/// - [Winsock]
/// - [FreeBSD]
/// - [NetBSD]
/// - [OpenBSD]
///
/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes
#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
#[inline]
#[doc(alias = "FIONREAD")]
pub fn ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64> {
// SAFETY: FIONREAD is a getter opcode that gets a c_int.
unsafe {
let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::FIONREAD }>, c::c_int>::new();
ioctl::ioctl(fd, ctl).map(|n| n as u64)
}
}