1 //! The Unix `ioctl` function is effectively lots of different functions hidden
2 //! behind a single dynamic dispatch interface. In order to provide a type-safe
3 //! API, rustix makes them all separate functions so that they can have
4 //! dedicated static type signatures.
5 //!
6 //! Some ioctls, such as those related to filesystems, terminals, and
7 //! processes, live in other top-level API modules.
8
9 #![allow(unsafe_code)]
10
11 use crate::{backend, io, ioctl};
12 use backend::c;
13 use backend::fd::AsFd;
14
15 /// `ioctl(fd, FIOCLEX, NULL)`—Set the close-on-exec flag.
16 ///
17 /// This is similar to `fcntl(fd, F_SETFD, FD_CLOEXEC)`, except that it avoids
18 /// clearing any other flags that might be set.
19 #[cfg(apple)]
20 #[inline]
21 #[doc(alias = "FIOCLEX")]
22 #[doc(alias = "FD_CLOEXEC")]
ioctl_fioclex<Fd: AsFd>(fd: Fd) -> io::Result<()>23 pub fn ioctl_fioclex<Fd: AsFd>(fd: Fd) -> io::Result<()> {
24 // SAFETY: FIOCLEX is a no-argument setter opcode.
25 unsafe {
26 let ctl = ioctl::NoArg::<ioctl::BadOpcode<{ c::FIOCLEX }>>::new();
27 ioctl::ioctl(fd, ctl)
28 }
29 }
30
31 /// `ioctl(fd, FIONBIO, &value)`—Enables or disables non-blocking mode.
32 ///
33 /// # References
34 /// - [Winsock]
35 /// - [NetBSD]
36 /// - [OpenBSD]
37 ///
38 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes
39 /// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS
40 /// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS
41 #[inline]
42 #[doc(alias = "FIONBIO")]
ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()>43 pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
44 // SAFETY: FIONBIO is a pointer setter opcode.
45 unsafe {
46 let ctl = ioctl::Setter::<ioctl::BadOpcode<{ c::FIONBIO }>, c::c_int>::new(value.into());
47 ioctl::ioctl(fd, ctl)
48 }
49 }
50
51 /// `ioctl(fd, FIONREAD)`—Returns the number of bytes ready to be read.
52 ///
53 /// The result of this function gets silently coerced into a C `int` by the OS,
54 /// so it may contain a wrapped value.
55 ///
56 /// # References
57 /// - [Linux]
58 /// - [Winsock]
59 /// - [FreeBSD]
60 /// - [NetBSD]
61 /// - [OpenBSD]
62 ///
63 /// [Linux]: https://man7.org/linux/man-pages/man2/ioctl_tty.2.html
64 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes
65 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=ioctl&sektion=2#GENERIC%09IOCTLS
66 /// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS
67 /// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS
68 #[cfg(not(any(target_os = "espidf", target_os = "vita")))]
69 #[inline]
70 #[doc(alias = "FIONREAD")]
ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64>71 pub fn ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64> {
72 // SAFETY: FIONREAD is a getter opcode that gets a c_int.
73 unsafe {
74 let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::FIONREAD }>, c::c_int>::new();
75 ioctl::ioctl(fd, ctl).map(|n| n as u64)
76 }
77 }
78