1 | /// The datatype used for the ioctl number |
2 | #[cfg (any(target_os = "android" , target_env = "musl" ))] |
3 | #[doc (hidden)] |
4 | pub type ioctl_num_type = ::libc::c_int; |
5 | #[cfg (not(any(target_os = "android" , target_env = "musl" )))] |
6 | #[doc (hidden)] |
7 | pub type ioctl_num_type = ::libc::c_ulong; |
8 | /// The datatype used for the 3rd argument |
9 | #[doc (hidden)] |
10 | pub type ioctl_param_type = ::libc::c_ulong; |
11 | |
12 | #[doc (hidden)] |
13 | pub const NRBITS: ioctl_num_type = 8; |
14 | #[doc (hidden)] |
15 | pub const TYPEBITS: ioctl_num_type = 8; |
16 | |
17 | #[cfg (any( |
18 | target_arch = "mips" , |
19 | target_arch = "mips64" , |
20 | target_arch = "powerpc" , |
21 | target_arch = "powerpc64" , |
22 | target_arch = "sparc64" |
23 | ))] |
24 | mod consts { |
25 | #[doc (hidden)] |
26 | pub const NONE: u8 = 1; |
27 | #[doc (hidden)] |
28 | pub const READ: u8 = 2; |
29 | #[doc (hidden)] |
30 | pub const WRITE: u8 = 4; |
31 | #[doc (hidden)] |
32 | pub const SIZEBITS: u8 = 13; |
33 | #[doc (hidden)] |
34 | pub const DIRBITS: u8 = 3; |
35 | } |
36 | |
37 | // "Generic" ioctl protocol |
38 | #[cfg (any( |
39 | target_arch = "x86" , |
40 | target_arch = "arm" , |
41 | target_arch = "s390x" , |
42 | target_arch = "x86_64" , |
43 | target_arch = "aarch64" , |
44 | target_arch = "riscv32" , |
45 | target_arch = "riscv64" |
46 | ))] |
47 | mod consts { |
48 | #[doc (hidden)] |
49 | pub const NONE: u8 = 0; |
50 | #[doc (hidden)] |
51 | pub const READ: u8 = 2; |
52 | #[doc (hidden)] |
53 | pub const WRITE: u8 = 1; |
54 | #[doc (hidden)] |
55 | pub const SIZEBITS: u8 = 14; |
56 | #[doc (hidden)] |
57 | pub const DIRBITS: u8 = 2; |
58 | } |
59 | |
60 | pub use self::consts::*; |
61 | |
62 | #[doc (hidden)] |
63 | pub const NRSHIFT: ioctl_num_type = 0; |
64 | #[doc (hidden)] |
65 | pub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type; |
66 | #[doc (hidden)] |
67 | pub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type; |
68 | #[doc (hidden)] |
69 | pub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type; |
70 | |
71 | #[doc (hidden)] |
72 | pub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1; |
73 | #[doc (hidden)] |
74 | pub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1; |
75 | #[doc (hidden)] |
76 | pub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1; |
77 | #[doc (hidden)] |
78 | pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1; |
79 | |
80 | /// Encode an ioctl command. |
81 | #[macro_export ] |
82 | #[doc (hidden)] |
83 | macro_rules! ioc { |
84 | ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => { |
85 | (($dir as $crate::sys::ioctl::ioctl_num_type |
86 | & $crate::sys::ioctl::DIRMASK) |
87 | << $crate::sys::ioctl::DIRSHIFT) |
88 | | (($ty as $crate::sys::ioctl::ioctl_num_type |
89 | & $crate::sys::ioctl::TYPEMASK) |
90 | << $crate::sys::ioctl::TYPESHIFT) |
91 | | (($nr as $crate::sys::ioctl::ioctl_num_type |
92 | & $crate::sys::ioctl::NRMASK) |
93 | << $crate::sys::ioctl::NRSHIFT) |
94 | | (($sz as $crate::sys::ioctl::ioctl_num_type |
95 | & $crate::sys::ioctl::SIZEMASK) |
96 | << $crate::sys::ioctl::SIZESHIFT) |
97 | }; |
98 | } |
99 | |
100 | /// Generate an ioctl request code for a command that passes no data. |
101 | /// |
102 | /// This is equivalent to the `_IO()` macro exposed by the C ioctl API. |
103 | /// |
104 | /// You should only use this macro directly if the `ioctl` you're working |
105 | /// with is "bad" and you cannot use `ioctl_none!()` directly. |
106 | /// |
107 | /// # Example |
108 | /// |
109 | /// ``` |
110 | /// # #[macro_use ] extern crate nix; |
111 | /// const KVMIO: u8 = 0xAE; |
112 | /// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); |
113 | /// # fn main() {} |
114 | /// ``` |
115 | #[macro_export (local_inner_macros)] |
116 | macro_rules! request_code_none { |
117 | ($ty:expr, $nr:expr) => { |
118 | ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0) |
119 | }; |
120 | } |
121 | |
122 | /// Generate an ioctl request code for a command that reads. |
123 | /// |
124 | /// This is equivalent to the `_IOR()` macro exposed by the C ioctl API. |
125 | /// |
126 | /// You should only use this macro directly if the `ioctl` you're working |
127 | /// with is "bad" and you cannot use `ioctl_read!()` directly. |
128 | /// |
129 | /// The read/write direction is relative to userland, so this |
130 | /// command would be userland is reading and the kernel is |
131 | /// writing. |
132 | #[macro_export (local_inner_macros)] |
133 | macro_rules! request_code_read { |
134 | ($ty:expr, $nr:expr, $sz:expr) => { |
135 | ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz) |
136 | }; |
137 | } |
138 | |
139 | /// Generate an ioctl request code for a command that writes. |
140 | /// |
141 | /// This is equivalent to the `_IOW()` macro exposed by the C ioctl API. |
142 | /// |
143 | /// You should only use this macro directly if the `ioctl` you're working |
144 | /// with is "bad" and you cannot use `ioctl_write!()` directly. |
145 | /// |
146 | /// The read/write direction is relative to userland, so this |
147 | /// command would be userland is writing and the kernel is |
148 | /// reading. |
149 | #[macro_export (local_inner_macros)] |
150 | macro_rules! request_code_write { |
151 | ($ty:expr, $nr:expr, $sz:expr) => { |
152 | ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz) |
153 | }; |
154 | } |
155 | |
156 | /// Generate an ioctl request code for a command that reads and writes. |
157 | /// |
158 | /// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API. |
159 | /// |
160 | /// You should only use this macro directly if the `ioctl` you're working |
161 | /// with is "bad" and you cannot use `ioctl_readwrite!()` directly. |
162 | #[macro_export (local_inner_macros)] |
163 | macro_rules! request_code_readwrite { |
164 | ($ty:expr, $nr:expr, $sz:expr) => { |
165 | ioc!( |
166 | $crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, |
167 | $ty, |
168 | $nr, |
169 | $sz |
170 | ) |
171 | }; |
172 | } |
173 | |