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