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