1 #[doc(hidden)]
2 pub const NRBITS: u32 = 8;
3 #[doc(hidden)]
4 pub const TYPEBITS: u32 = 8;
5
6 #[cfg(any(target_os = "linux", target_os = "android"))]
7 #[path = "linux.rs"]
8 mod consts;
9
10 #[cfg(target_os = "macos")]
11 #[path = "macos.rs"]
12 mod consts;
13
14 #[doc(hidden)]
15 pub use self::consts::*;
16
17 #[doc(hidden)]
18 pub const NRSHIFT: u32 = 0;
19 #[doc(hidden)]
20 pub const TYPESHIFT: u32 = NRSHIFT + NRBITS as u32;
21 #[doc(hidden)]
22 pub const SIZESHIFT: u32 = TYPESHIFT + TYPEBITS as u32;
23 #[doc(hidden)]
24 pub const DIRSHIFT: u32 = SIZESHIFT + SIZEBITS as u32;
25
26 #[doc(hidden)]
27 pub const NRMASK: u32 = (1 << NRBITS) - 1;
28 #[doc(hidden)]
29 pub const TYPEMASK: u32 = (1 << TYPEBITS) - 1;
30 #[doc(hidden)]
31 pub const SIZEMASK: u32 = (1 << SIZEBITS) - 1;
32 #[doc(hidden)]
33 pub const DIRMASK: u32 = (1 << DIRBITS) - 1;
34
35 /// Encode an ioctl command.
36 #[macro_export]
37 macro_rules! ioc {
38 ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => {
39 (($dir as u32) << $crate::DIRSHIFT)
40 | (($ty as u32) << $crate::TYPESHIFT)
41 | (($nr as u32) << $crate::NRSHIFT)
42 | (($sz as u32) << $crate::SIZESHIFT)
43 };
44 }
45
46 /// Encode an ioctl command that has no associated data.
47 #[macro_export]
48 macro_rules! io {
49 ($ty:expr, $nr:expr) => {
50 $crate::ioc!($crate::NONE, $ty, $nr, 0)
51 };
52 }
53
54 /// Encode an ioctl command that reads.
55 #[macro_export]
56 macro_rules! ior {
57 ($ty:expr, $nr:expr, $sz:expr) => {
58 $crate::ioc!($crate::READ, $ty, $nr, $sz)
59 };
60 }
61
62 /// Encode an ioctl command that writes.
63 #[macro_export]
64 macro_rules! iow {
65 ($ty:expr, $nr:expr, $sz:expr) => {
66 $crate::ioc!($crate::WRITE, $ty, $nr, $sz)
67 };
68 }
69
70 /// Encode an ioctl command that both reads and writes.
71 #[macro_export]
72 macro_rules! iorw {
73 ($ty:expr, $nr:expr, $sz:expr) => {
74 $crate::ioc!($crate::READ | $crate::WRITE, $ty, $nr, $sz)
75 };
76 }
77
78 /// Declare a wrapper function around an ioctl.
79 #[macro_export]
80 macro_rules! ioctl {
81 (bad $name:ident with $nr:expr) => {
82 pub unsafe fn $name(fd: ::std::os::raw::c_int, data: *mut u8) -> ::std::os::raw::c_int {
83 $crate::ioctl(fd, $nr as ::std::os::raw::c_ulong, data)
84 }
85 };
86 (bad read $name:ident with $nr:expr; $ty:ty) => {
87 pub unsafe fn $name(fd: ::std::os::raw::c_int, data: *mut $ty) -> ::std::os::raw::c_int {
88 $crate::ioctl(fd, $nr as ::std::os::raw::c_ulong, data)
89 }
90 };
91 (bad write $name:ident with $nr:expr; $ty:ty) => {
92 pub unsafe fn $name(fd: ::std::os::raw::c_int, data: *const $ty) -> ::std::os::raw::c_int {
93 $crate::ioctl(fd, $nr as ::std::os::raw::c_ulong, data)
94 }
95 };
96 (none $name:ident with $ioty:expr, $nr:expr) => {
97 pub unsafe fn $name(fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int {
98 $crate::ioctl(fd, $crate::io!($ioty, $nr) as ::std::os::raw::c_ulong)
99 }
100 };
101 (try none $name:ident with $ioty:expr, $nr:expr) => {
102 pub unsafe fn $name(fd: ::std::os::raw::c_int) -> std::result::Result<(), std::io::Error> {
103 $crate::check_res($crate::ioctl(
104 fd,
105 $crate::io!($ioty, $nr) as ::std::os::raw::c_ulong,
106 ))
107 }
108 };
109 (arg $name:ident with $ioty:expr, $nr:expr) => {
110 pub unsafe fn $name(
111 fd: ::std::os::raw::c_int,
112 arg: ::std::os::raw::c_ulong,
113 ) -> ::std::os::raw::c_int {
114 $crate::ioctl(fd, $crate::io!($ioty, $nr) as ::std::os::raw::c_ulong, arg)
115 }
116 };
117 (read $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
118 pub unsafe fn $name(fd: ::std::os::raw::c_int, val: *mut $ty) -> ::std::os::raw::c_int {
119 $crate::ioctl(
120 fd,
121 $crate::ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
122 val,
123 )
124 }
125 };
126 (try read $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
127 pub unsafe fn $name(
128 fd: ::std::os::raw::c_int,
129 val: *mut $ty,
130 ) -> std::result::Result<(), std::io::Error> {
131 $crate::check_res($crate::ioctl(
132 fd,
133 $crate::ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
134 val,
135 ))
136 }
137 };
138 (try read0 $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
139 pub unsafe fn $name(fd: ::std::os::raw::c_int) -> std::result::Result<$ty, std::io::Error> {
140 let mut val: $ty = std::mem::zeroed();
141 $crate::check_res($crate::ioctl(
142 fd,
143 $crate::ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
144 &mut val as *mut $ty,
145 ))
146 .map(|_| val)
147 }
148 };
149 (write $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
150 pub unsafe fn $name(fd: ::std::os::raw::c_int, val: *const $ty) -> ::std::os::raw::c_int {
151 $crate::ioctl(
152 fd,
153 $crate::iow!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
154 val,
155 )
156 }
157 };
158 (try write $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
159 pub unsafe fn $name(
160 fd: ::std::os::raw::c_int,
161 val: *const $ty,
162 ) -> std::result::Result<(), std::io::Error> {
163 $crate::check_res($crate::ioctl(
164 fd,
165 $crate::iow!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
166 val,
167 ))
168 }
169 };
170 (readwrite $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
171 pub unsafe fn $name(fd: ::std::os::raw::c_int, val: *mut $ty) -> ::std::os::raw::c_int {
172 $crate::ioctl(
173 fd,
174 $crate::iorw!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
175 val,
176 )
177 }
178 };
179 (try readwrite $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
180 pub unsafe fn $name(
181 fd: ::std::os::raw::c_int,
182 val: *mut $ty,
183 ) -> std::result::Result<(), std::io::Error> {
184 $crate::check_res($crate::ioctl(
185 fd,
186 $crate::iorw!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
187 val,
188 ))
189 }
190 };
191 (read buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
192 pub unsafe fn $name(
193 fd: ::std::os::raw::c_int,
194 val: *mut $ty,
195 len: usize,
196 ) -> ::std::os::raw::c_int {
197 $crate::ioctl(
198 fd,
199 $crate::ior!($ioty, $nr, len) as ::std::os::raw::c_ulong,
200 val,
201 )
202 }
203 };
204 (write buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
205 pub unsafe fn $name(
206 fd: ::std::os::raw::c_int,
207 val: *const $ty,
208 len: usize,
209 ) -> ::std::os::raw::c_int {
210 $crate::ioctl(
211 fd,
212 $crate::iow!($ioty, $nr, len) as ::std::os::raw::c_ulong,
213 val,
214 )
215 }
216 };
217 (readwrite buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
218 pub unsafe fn $name(
219 fd: ::std::os::raw::c_int,
220 val: *const $ty,
221 len: usize,
222 ) -> ::std::os::raw::c_int {
223 $crate::ioctl(
224 fd,
225 $crate::iorw!($ioty, $nr, len) as ::std::os::raw::c_ulong,
226 val,
227 )
228 }
229 };
230 }
231
232 /// Extracts the "direction" (read/write/none) from an encoded ioctl command.
233 #[inline(always)]
ioc_dir(nr: u32) -> u8234 pub fn ioc_dir(nr: u32) -> u8 {
235 ((nr >> DIRSHIFT) & DIRMASK) as u8
236 }
237
238 /// Extracts the type from an encoded ioctl command.
239 #[inline(always)]
ioc_type(nr: u32) -> u32240 pub fn ioc_type(nr: u32) -> u32 {
241 (nr >> TYPESHIFT) & TYPEMASK
242 }
243
244 /// Extracts the ioctl number from an encoded ioctl command.
245 #[inline(always)]
ioc_nr(nr: u32) -> u32246 pub fn ioc_nr(nr: u32) -> u32 {
247 (nr >> NRSHIFT) & NRMASK
248 }
249
250 /// Extracts the size from an encoded ioctl command.
251 #[inline(always)]
ioc_size(nr: u32) -> u32252 pub fn ioc_size(nr: u32) -> u32 {
253 ((nr >> SIZESHIFT) as u32) & SIZEMASK
254 }
255
256 #[doc(hidden)]
257 pub const IN: u32 = (WRITE as u32) << DIRSHIFT;
258 #[doc(hidden)]
259 pub const OUT: u32 = (READ as u32) << DIRSHIFT;
260 #[doc(hidden)]
261 pub const INOUT: u32 = ((READ | WRITE) as u32) << DIRSHIFT;
262 #[doc(hidden)]
263 pub const SIZE_MASK: u32 = SIZEMASK << SIZESHIFT;
264