172 lines
5.1 KiB
Rust
172 lines
5.1 KiB
Rust
/// 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
|
|
)
|
|
};
|
|
}
|