/// The datatype used for the ioctl number #[cfg(any(target_os = "android", target_env = "musl"))] #[doc(hidden)] pub type ioctl_num_type = ::libc::c_int; #[cfg(not(any(target_os = "android", target_env = "musl")))] #[doc(hidden)] pub type ioctl_num_type = ::libc::c_ulong; /// The datatype used for the 3rd argument #[doc(hidden)] pub type ioctl_param_type = ::libc::c_ulong; #[doc(hidden)] pub const NRBITS: ioctl_num_type = 8; #[doc(hidden)] pub const TYPEBITS: ioctl_num_type = 8; #[cfg(any( target_arch = "mips", target_arch = "mips64", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "sparc64" ))] mod consts { #[doc(hidden)] pub const NONE: u8 = 1; #[doc(hidden)] pub const READ: u8 = 2; #[doc(hidden)] pub const WRITE: u8 = 4; #[doc(hidden)] pub const SIZEBITS: u8 = 13; #[doc(hidden)] pub const DIRBITS: u8 = 3; } // "Generic" ioctl protocol #[cfg(any( target_arch = "x86", target_arch = "arm", target_arch = "s390x", target_arch = "x86_64", target_arch = "aarch64", target_arch = "riscv32", target_arch = "riscv64" ))] mod consts { #[doc(hidden)] pub const NONE: u8 = 0; #[doc(hidden)] pub const READ: u8 = 2; #[doc(hidden)] pub const WRITE: u8 = 1; #[doc(hidden)] pub const SIZEBITS: u8 = 14; #[doc(hidden)] pub const DIRBITS: u8 = 2; } pub use self::consts::*; #[doc(hidden)] pub const NRSHIFT: ioctl_num_type = 0; #[doc(hidden)] pub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type; #[doc(hidden)] pub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type; #[doc(hidden)] pub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type; #[doc(hidden)] pub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1; #[doc(hidden)] pub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1; #[doc(hidden)] pub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1; #[doc(hidden)] pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1; /// Encode an ioctl command. #[macro_export] #[doc(hidden)] macro_rules! ioc { ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => { (($dir as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::DIRMASK) << $crate::sys::ioctl::DIRSHIFT) | (($ty as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::TYPEMASK) << $crate::sys::ioctl::TYPESHIFT) | (($nr as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::NRMASK) << $crate::sys::ioctl::NRSHIFT) | (($sz as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::SIZEMASK) << $crate::sys::ioctl::SIZESHIFT) }; } /// Generate an ioctl request code for a command that passes no data. /// /// This is equivalent to the `_IO()` macro exposed by the C ioctl API. /// /// You should only use this macro directly if the `ioctl` you're working /// with is "bad" and you cannot use `ioctl_none!()` directly. /// /// # Example /// /// ``` /// # #[macro_use] extern crate nix; /// const KVMIO: u8 = 0xAE; /// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); /// # fn main() {} /// ``` #[macro_export(local_inner_macros)] macro_rules! request_code_none { ($ty:expr, $nr:expr) => { ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0) }; } /// Generate an ioctl request code for a command that reads. /// /// This is equivalent to the `_IOR()` macro exposed by the C ioctl API. /// /// You should only use this macro directly if the `ioctl` you're working /// with is "bad" and you cannot use `ioctl_read!()` directly. /// /// The read/write direction is relative to userland, so this /// command would be userland is reading and the kernel is /// writing. #[macro_export(local_inner_macros)] macro_rules! request_code_read { ($ty:expr, $nr:expr, $sz:expr) => { ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz) }; } /// Generate an ioctl request code for a command that writes. /// /// This is equivalent to the `_IOW()` macro exposed by the C ioctl API. /// /// You should only use this macro directly if the `ioctl` you're working /// with is "bad" and you cannot use `ioctl_write!()` directly. /// /// The read/write direction is relative to userland, so this /// command would be userland is writing and the kernel is /// reading. #[macro_export(local_inner_macros)] macro_rules! request_code_write { ($ty:expr, $nr:expr, $sz:expr) => { ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz) }; } /// Generate an ioctl request code for a command that reads and writes. /// /// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API. /// /// You should only use this macro directly if the `ioctl` you're working /// with is "bad" and you cannot use `ioctl_readwrite!()` directly. #[macro_export(local_inner_macros)] macro_rules! request_code_readwrite { ($ty:expr, $nr:expr, $sz:expr) => { ioc!( $crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, $ty, $nr, $sz ) }; }