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