ioctl_sys/platform/
mod.rs

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