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