1/// The datatype used for the ioctl number
2#[cfg(any(target_os = "android", target_env = "musl"))]
3#[doc(hidden)]
4pub type ioctl_num_type = ::libc::c_int;
5#[cfg(not(any(target_os = "android", target_env = "musl")))]
6#[doc(hidden)]
7pub type ioctl_num_type = ::libc::c_ulong;
8/// The datatype used for the 3rd argument
9#[doc(hidden)]
10pub type ioctl_param_type = ::libc::c_ulong;
11
12#[doc(hidden)]
13pub const NRBITS: ioctl_num_type = 8;
14#[doc(hidden)]
15pub 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))]
24mod 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))]
47mod 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
60pub use self::consts::*;
61
62#[doc(hidden)]
63pub const NRSHIFT: ioctl_num_type = 0;
64#[doc(hidden)]
65pub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type;
66#[doc(hidden)]
67pub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type;
68#[doc(hidden)]
69pub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type;
70
71#[doc(hidden)]
72pub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1;
73#[doc(hidden)]
74pub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1;
75#[doc(hidden)]
76pub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1;
77#[doc(hidden)]
78pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1;
79
80/// Encode an ioctl command.
81#[macro_export]
82#[doc(hidden)]
83macro_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)]
116macro_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)]
133macro_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)]
150macro_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)]
163macro_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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more