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