1//! The Unix `ioctl` function is effectively lots of different functions
2//! hidden behind a single dynamic dispatch interface. In order to provide
3//! a type-safe API, rustix makes them all separate functions so that they
4//! can have dedicated static type signatures.
5
6use crate::{backend, io};
7use backend::fd::AsFd;
8
9/// `ioctl(fd, TIOCEXCL)`—Enables exclusive mode on a terminal.
10///
11/// # References
12/// - [Linux]
13/// - [FreeBSD]
14/// - [NetBSD]
15/// - [OpenBSD]
16///
17/// [Linux]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html
18/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=tty&sektion=4
19/// [NetBSD]: https://man.netbsd.org/tty.4
20/// [OpenBSD]: https://man.openbsd.org/tty.4
21#[cfg(not(any(windows, target_os = "haiku", target_os = "redox", target_os = "wasi")))]
22#[inline]
23#[doc(alias = "TIOCEXCL")]
24pub fn ioctl_tiocexcl<Fd: AsFd>(fd: Fd) -> io::Result<()> {
25 backend::io::syscalls::ioctl_tiocexcl(fd.as_fd())
26}
27
28/// `ioctl(fd, TIOCNXCL)`—Disables exclusive mode on a terminal.
29///
30/// # References
31/// - [Linux]
32/// - [FreeBSD]
33/// - [NetBSD]
34/// - [OpenBSD]
35///
36/// [Linux]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html
37/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=tty&sektion=4
38/// [NetBSD]: https://man.netbsd.org/tty.4
39/// [OpenBSD]: https://man.openbsd.org/tty.4
40#[cfg(not(any(windows, target_os = "haiku", target_os = "redox", target_os = "wasi")))]
41#[inline]
42#[doc(alias = "TIOCNXCL")]
43pub fn ioctl_tiocnxcl<Fd: AsFd>(fd: Fd) -> io::Result<()> {
44 backend::io::syscalls::ioctl_tiocnxcl(fd.as_fd())
45}
46
47/// `ioctl(fd, FIOCLEX, NULL)`—Set the close-on-exec flag.
48///
49/// Also known as `fcntl(fd, F_SETFD, FD_CLOEXEC)`.
50///
51/// # References
52/// - [Winsock2]
53/// - [NetBSD]
54/// - [OpenBSD]
55///
56/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-ioctlsocket
57/// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS
58/// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS
59#[cfg(apple)]
60#[inline]
61#[doc(alias = "FIOCLEX")]
62#[doc(alias = "FD_CLOEXEC")]
63pub fn ioctl_fioclex<Fd: AsFd>(fd: Fd) -> io::Result<()> {
64 backend::io::syscalls::ioctl_fioclex(fd.as_fd())
65}
66
67/// `ioctl(fd, FIONBIO, &value)`—Enables or disables non-blocking mode.
68///
69/// # References
70/// - [Winsock2]
71/// - [NetBSD]
72/// - [OpenBSD]
73///
74/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes
75/// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS
76/// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS
77#[inline]
78#[doc(alias = "FIONBIO")]
79pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
80 backend::io::syscalls::ioctl_fionbio(fd.as_fd(), value)
81}
82
83/// `ioctl(fd, FIONREAD)`—Returns the number of bytes ready to be read.
84///
85/// The result of this function gets silently coerced into a C `int`
86/// by the OS, so it may contain a wrapped value.
87///
88/// # References
89/// - [Linux]
90/// - [Winsock2]
91/// - [FreeBSD]
92/// - [NetBSD]
93/// - [OpenBSD]
94///
95/// [Linux]: https://man7.org/linux/man-pages/man2/ioctl_tty.2.html
96/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes
97/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=ioctl&sektion=2#GENERIC%09IOCTLS
98/// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS
99/// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS
100#[cfg(not(target_os = "redox"))]
101#[inline]
102#[doc(alias = "FIONREAD")]
103pub fn ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64> {
104 backend::io::syscalls::ioctl_fionread(fd.as_fd())
105}
106
107/// `ioctl(fd, BLKSSZGET)`—Returns the logical block size of a block device.
108///
109/// This is mentioned in the [Linux `openat` manual page].
110///
111/// [Linux `openat` manual page]: https://man7.org/linux/man-pages/man2/openat.2.html
112#[cfg(linux_kernel)]
113#[inline]
114#[doc(alias = "BLKSSZGET")]
115pub fn ioctl_blksszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
116 backend::io::syscalls::ioctl_blksszget(fd.as_fd())
117}
118
119/// `ioctl(fd, BLKPBSZGET)`—Returns the physical block size of a block device.
120#[cfg(linux_kernel)]
121#[inline]
122#[doc(alias = "BLKPBSZGET")]
123pub fn ioctl_blkpbszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
124 backend::io::syscalls::ioctl_blkpbszget(fd.as_fd())
125}
126
127/// `ioctl(fd, FICLONE, src_fd)`—Share data between open files.
128///
129/// This ioctl is not available on Sparc platforms
130///
131/// # References
132/// - [Linux]
133///
134/// [Linux]: https://man7.org/linux/man-pages/man2/ioctl_ficlone.2.html
135#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))]
136#[inline]
137#[doc(alias = "FICLONE")]
138pub fn ioctl_ficlone<Fd: AsFd, SrcFd: AsFd>(fd: Fd, src_fd: SrcFd) -> io::Result<()> {
139 backend::io::syscalls::ioctl_ficlone(fd.as_fd(), src_fd:src_fd.as_fd())
140}
141
142/// `ioctl(fd, EXT4_IOC_RESIZE_FS, blocks)`—Resize ext4 filesystem on fd.
143#[cfg(linux_kernel)]
144#[inline]
145#[doc(alias = "EXT4_IOC_RESIZE_FS")]
146pub fn ext4_ioc_resize_fs<Fd: AsFd>(fd: Fd, blocks: u64) -> io::Result<()> {
147 backend::io::syscalls::ext4_ioc_resize_fs(fd.as_fd(), blocks)
148}
149