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 | /// Also known as `fcntl(fd, F_SETFD, FD_CLOEXEC)`. |
18 | /// |
19 | /// # References |
20 | /// - [Winsock2] |
21 | /// - [NetBSD] |
22 | /// - [OpenBSD] |
23 | /// |
24 | /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-ioctlsocket |
25 | /// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS |
26 | /// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS |
27 | #[cfg (apple)] |
28 | #[inline ] |
29 | #[doc (alias = "FIOCLEX" )] |
30 | #[doc (alias = "FD_CLOEXEC" )] |
31 | pub fn ioctl_fioclex<Fd: AsFd>(fd: Fd) -> io::Result<()> { |
32 | // SAFETY: FIOCLEX is a no-argument setter opcode. |
33 | unsafe { |
34 | let ctl = ioctl::NoArg::<ioctl::BadOpcode<{ c::FIOCLEX }>>::new(); |
35 | ioctl::ioctl(fd, ctl) |
36 | } |
37 | } |
38 | |
39 | /// `ioctl(fd, FIONBIO, &value)`—Enables or disables non-blocking mode. |
40 | /// |
41 | /// # References |
42 | /// - [Winsock2] |
43 | /// - [NetBSD] |
44 | /// - [OpenBSD] |
45 | /// |
46 | /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes |
47 | /// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS |
48 | /// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS |
49 | #[inline ] |
50 | #[doc (alias = "FIONBIO" )] |
51 | pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { |
52 | // SAFETY: FIONBIO is a pointer setter opcode. |
53 | unsafe { |
54 | let ctl: Setter, …> = ioctl::Setter::<ioctl::BadOpcode<{ c::FIONBIO }>, c::c_int>::new(input:value.into()); |
55 | ioctl::ioctl(fd, ioctl:ctl) |
56 | } |
57 | } |
58 | |
59 | /// `ioctl(fd, FIONREAD)`—Returns the number of bytes ready to be read. |
60 | /// |
61 | /// The result of this function gets silently coerced into a C `int` |
62 | /// by the OS, so it may contain a wrapped value. |
63 | /// |
64 | /// # References |
65 | /// - [Linux] |
66 | /// - [Winsock2] |
67 | /// - [FreeBSD] |
68 | /// - [NetBSD] |
69 | /// - [OpenBSD] |
70 | /// |
71 | /// [Linux]: https://man7.org/linux/man-pages/man2/ioctl_tty.2.html |
72 | /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes |
73 | /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=ioctl&sektion=2#GENERIC%09IOCTLS |
74 | /// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS |
75 | /// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS |
76 | #[cfg (not(target_os = "espidf" ))] |
77 | #[inline ] |
78 | #[doc (alias = "FIONREAD" )] |
79 | pub fn ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64> { |
80 | // SAFETY: FIONREAD is a getter opcode that gets a c_int. |
81 | unsafe { |
82 | let ctl: Getter, …> = ioctl::Getter::<ioctl::BadOpcode<{ c::FIONREAD }>, c::c_int>::new(); |
83 | ioctl::ioctl(fd, ctl).map(|n: i32| n as u64) |
84 | } |
85 | } |
86 | |