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