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