ioctl_gen/lib.rs
1//! This crate lets you encode and decode ioctl numbers.
2//! It's pretty much just a port of `ioctl.h`.
3//!
4//! Here are some examples:
5//!
6//! ```
7//! #[macro_use]
8//! extern crate ioctlify;
9//!
10//! # fn main() {
11//! // Taken from <linux/videodev2.h>
12//! const VIDIOC_RESERVED: u32 = io!(b'V', 1);
13//! const VIDIOC_STREAMON: u32 = iow!(b'V', 18, 4);
14//! const VIDIOC_LOG_STATUS: u32 = io!(b'V', 70);
15//!
16//! assert_eq!(ioc_type!(VIDIOC_RESERVED), b'V' as u32);
17//! assert_eq!(VIDIOC_STREAMON, 1074026002);
18//! assert_eq!(ioc_nr!(VIDIOC_LOG_STATUS), 70);
19//! # }
20//! ```
21
22//TODO: Nonstandard platforms.
23//TODO: When will mem::size_of become a const-fn?
24
25/// The number of bits used for the number field.
26pub const NRBITS: u32 = 8;
27/// The number of bits used for the type field.
28pub const TYPEBITS: u32 = 8;
29/// The number of bits used for the size field.
30pub const SIZEBITS: u32 = 14;
31/// The number of bits used for the direction field.
32pub const DIRBITS: u32 = 2;
33/// Neither direction.
34pub const NONE: u32 = 0;
35/// The write direction.
36pub const WRITE: u32 = 1;
37/// The read direction.
38pub const READ: u32 = 2;
39
40/// Bitmask for the number field.
41pub const NRMASK: u32 = (1 << NRBITS) - 1;
42/// Bitmask for the type field.
43pub const TYPEMASK: u32 = (1 << TYPEBITS) - 1;
44/// Bitmask for the size field.
45pub const SIZEMASK: u32 = (1 << SIZEBITS) - 1;
46/// Bitmask for the direction field.
47pub const DIRMASK: u32 = (1 << DIRBITS) - 1;
48
49/// Offset of the number field.
50pub const NRSHIFT: u32 = 0;
51/// Offset of the type field.
52pub const TYPESHIFT: u32 = NRSHIFT + NRBITS;
53/// Offset of the size field.
54pub const SIZESHIFT: u32 = TYPESHIFT + TYPEBITS;
55/// Offset of the direction field.
56pub const DIRSHIFT: u32 = SIZESHIFT + SIZEBITS;
57
58/// Creates the ioctl number for the given data.
59///
60/// `io`, `ior`, `iow` and `iowr` are preferred over this macro.
61#[macro_export]
62macro_rules! ioc {
63 ($dr:expr, $ty:expr, $nr:expr, $sz:expr) => {
64 (($dr as u32) << $crate::DIRSHIFT) |
65 (($ty as u32) << $crate::TYPESHIFT) |
66 (($nr as u32) << $crate::NRSHIFT) |
67 (($sz as u32) << $crate::SIZESHIFT)
68 }
69}
70
71/// Creates the ioctl number for an operation that isn't reading or writing.
72#[macro_export]
73macro_rules! io {
74 ($ty:expr, $nr:expr) => {
75 ioc!($crate::NONE, $ty, $nr, 0)
76 }
77}
78
79/// Creates the ioctl number for a read-only operation.
80#[macro_export]
81macro_rules! ior {
82 ($ty:expr, $nr:expr, $sz:expr) => {
83 ioc!($crate::READ, $ty, $nr, $sz)
84 }
85}
86
87/// Creates the ioctl number for a write-only operation.
88#[macro_export]
89macro_rules! iow {
90 ($ty:expr, $nr:expr, $sz:expr) => {
91 ioc!($crate::WRITE, $ty, $nr, $sz)
92 }
93}
94
95/// Creates the ioctl number for a read/write operation.
96#[macro_export]
97macro_rules! iowr {
98 ($ty:expr, $nr:expr, $sz:expr) => {
99 ioc!($crate::READ | $crate::WRITE, $ty, $nr, $sz)
100 }
101}
102
103/// Decodes the access mode / direction from an ioctl number.
104#[macro_export]
105macro_rules! ioc_dir {
106 ($n:expr) => { ($n >> $crate::DIRSHIFT) & $crate::DIRMASK }
107}
108
109/// Decodes the type from an ioctl number.
110#[macro_export]
111macro_rules! ioc_type {
112 ($n:expr) => { ($n >> $crate::TYPESHIFT) & $crate::TYPEMASK }
113}
114
115/// Decodes the function number from an ioctl number.
116#[macro_export]
117macro_rules! ioc_nr {
118 ($n:expr) => { ($n >> $crate::NRSHIFT) & $crate::NRMASK }
119}
120
121/// Decodes the parameter size from an ioctl number.
122#[macro_export]
123macro_rules! ioc_size {
124 ($n:expr) => { ($n >> $crate::SIZESHIFT) & $crate::SIZEMASK }
125}
126