Revision control
Copy as Markdown
Other Tools
#[doc(hidden)]
pub const NRBITS: u32 = 8;
#[doc(hidden)]
pub const TYPEBITS: u32 = 8;
#[cfg(any(target_os = "linux", target_os = "android"))]
#[path = "linux.rs"]
mod consts;
#[cfg(target_os = "macos")]
#[path = "macos.rs"]
mod consts;
#[doc(hidden)]
pub use self::consts::*;
#[doc(hidden)]
pub const NRSHIFT: u32 = 0;
#[doc(hidden)]
pub const TYPESHIFT: u32 = NRSHIFT + NRBITS as u32;
#[doc(hidden)]
pub const SIZESHIFT: u32 = TYPESHIFT + TYPEBITS as u32;
#[doc(hidden)]
pub const DIRSHIFT: u32 = SIZESHIFT + SIZEBITS as u32;
#[doc(hidden)]
pub const NRMASK: u32 = (1 << NRBITS) - 1;
#[doc(hidden)]
pub const TYPEMASK: u32 = (1 << TYPEBITS) - 1;
#[doc(hidden)]
pub const SIZEMASK: u32 = (1 << SIZEBITS) - 1;
#[doc(hidden)]
pub const DIRMASK: u32 = (1 << DIRBITS) - 1;
/// Encode an ioctl command.
#[macro_export]
macro_rules! ioc {
($dir:expr, $ty:expr, $nr:expr, $sz:expr) => {
(($dir as u32) << $crate::DIRSHIFT)
| (($ty as u32) << $crate::TYPESHIFT)
| (($nr as u32) << $crate::NRSHIFT)
| (($sz as u32) << $crate::SIZESHIFT)
};
}
/// Encode an ioctl command that has no associated data.
#[macro_export]
macro_rules! io {
($ty:expr, $nr:expr) => {
$crate::ioc!($crate::NONE, $ty, $nr, 0)
};
}
/// Encode an ioctl command that reads.
#[macro_export]
macro_rules! ior {
($ty:expr, $nr:expr, $sz:expr) => {
$crate::ioc!($crate::READ, $ty, $nr, $sz)
};
}
/// Encode an ioctl command that writes.
#[macro_export]
macro_rules! iow {
($ty:expr, $nr:expr, $sz:expr) => {
$crate::ioc!($crate::WRITE, $ty, $nr, $sz)
};
}
/// Encode an ioctl command that both reads and writes.
#[macro_export]
macro_rules! iorw {
($ty:expr, $nr:expr, $sz:expr) => {
$crate::ioc!($crate::READ | $crate::WRITE, $ty, $nr, $sz)
};
}
/// Declare a wrapper function around an ioctl.
#[macro_export]
macro_rules! ioctl {
(bad $name:ident with $nr:expr) => {
pub unsafe fn $name(fd: ::std::os::raw::c_int, data: *mut u8) -> ::std::os::raw::c_int {
$crate::ioctl(fd, $nr as ::std::os::raw::c_ulong, data)
}
};
(bad read $name:ident with $nr:expr; $ty:ty) => {
pub unsafe fn $name(fd: ::std::os::raw::c_int, data: *mut $ty) -> ::std::os::raw::c_int {
$crate::ioctl(fd, $nr as ::std::os::raw::c_ulong, data)
}
};
(bad write $name:ident with $nr:expr; $ty:ty) => {
pub unsafe fn $name(fd: ::std::os::raw::c_int, data: *const $ty) -> ::std::os::raw::c_int {
$crate::ioctl(fd, $nr as ::std::os::raw::c_ulong, data)
}
};
(none $name:ident with $ioty:expr, $nr:expr) => {
pub unsafe fn $name(fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int {
$crate::ioctl(fd, $crate::io!($ioty, $nr) as ::std::os::raw::c_ulong)
}
};
(try none $name:ident with $ioty:expr, $nr:expr) => {
pub unsafe fn $name(fd: ::std::os::raw::c_int) -> std::result::Result<(), std::io::Error> {
$crate::check_res($crate::ioctl(
fd,
$crate::io!($ioty, $nr) as ::std::os::raw::c_ulong,
))
}
};
(arg $name:ident with $ioty:expr, $nr:expr) => {
pub unsafe fn $name(
fd: ::std::os::raw::c_int,
arg: ::std::os::raw::c_ulong,
) -> ::std::os::raw::c_int {
$crate::ioctl(fd, $crate::io!($ioty, $nr) as ::std::os::raw::c_ulong, arg)
}
};
(read $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
pub unsafe fn $name(fd: ::std::os::raw::c_int, val: *mut $ty) -> ::std::os::raw::c_int {
$crate::ioctl(
fd,
$crate::ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
val,
)
}
};
(try read $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
pub unsafe fn $name(
fd: ::std::os::raw::c_int,
val: *mut $ty,
) -> std::result::Result<(), std::io::Error> {
$crate::check_res($crate::ioctl(
fd,
$crate::ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
val,
))
}
};
(try read0 $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
pub unsafe fn $name(fd: ::std::os::raw::c_int) -> std::result::Result<$ty, std::io::Error> {
let mut val: $ty = std::mem::zeroed();
$crate::check_res($crate::ioctl(
fd,
$crate::ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
&mut val as *mut $ty,
))
.map(|_| val)
}
};
(write $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
pub unsafe fn $name(fd: ::std::os::raw::c_int, val: *const $ty) -> ::std::os::raw::c_int {
$crate::ioctl(
fd,
$crate::iow!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
val,
)
}
};
(try write $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
pub unsafe fn $name(
fd: ::std::os::raw::c_int,
val: *const $ty,
) -> std::result::Result<(), std::io::Error> {
$crate::check_res($crate::ioctl(
fd,
$crate::iow!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
val,
))
}
};
(readwrite $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
pub unsafe fn $name(fd: ::std::os::raw::c_int, val: *mut $ty) -> ::std::os::raw::c_int {
$crate::ioctl(
fd,
$crate::iorw!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
val,
)
}
};
(try readwrite $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
pub unsafe fn $name(
fd: ::std::os::raw::c_int,
val: *mut $ty,
) -> std::result::Result<(), std::io::Error> {
$crate::check_res($crate::ioctl(
fd,
$crate::iorw!($ioty, $nr, ::std::mem::size_of::<$ty>()) as ::std::os::raw::c_ulong,
val,
))
}
};
(read buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
pub unsafe fn $name(
fd: ::std::os::raw::c_int,
val: *mut $ty,
len: usize,
) -> ::std::os::raw::c_int {
$crate::ioctl(
fd,
$crate::ior!($ioty, $nr, len) as ::std::os::raw::c_ulong,
val,
)
}
};
(write buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
pub unsafe fn $name(
fd: ::std::os::raw::c_int,
val: *const $ty,
len: usize,
) -> ::std::os::raw::c_int {
$crate::ioctl(
fd,
$crate::iow!($ioty, $nr, len) as ::std::os::raw::c_ulong,
val,
)
}
};
(readwrite buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => {
pub unsafe fn $name(
fd: ::std::os::raw::c_int,
val: *const $ty,
len: usize,
) -> ::std::os::raw::c_int {
$crate::ioctl(
fd,
$crate::iorw!($ioty, $nr, len) as ::std::os::raw::c_ulong,
val,
)
}
};
}
/// Extracts the "direction" (read/write/none) from an encoded ioctl command.
#[inline(always)]
pub fn ioc_dir(nr: u32) -> u8 {
((nr >> DIRSHIFT) & DIRMASK) as u8
}
/// Extracts the type from an encoded ioctl command.
#[inline(always)]
pub fn ioc_type(nr: u32) -> u32 {
(nr >> TYPESHIFT) & TYPEMASK
}
/// Extracts the ioctl number from an encoded ioctl command.
#[inline(always)]
pub fn ioc_nr(nr: u32) -> u32 {
(nr >> NRSHIFT) & NRMASK
}
/// Extracts the size from an encoded ioctl command.
#[inline(always)]
pub fn ioc_size(nr: u32) -> u32 {
((nr >> SIZESHIFT) as u32) & SIZEMASK
}
#[doc(hidden)]
pub const IN: u32 = (WRITE as u32) << DIRSHIFT;
#[doc(hidden)]
pub const OUT: u32 = (READ as u32) << DIRSHIFT;
#[doc(hidden)]
pub const INOUT: u32 = ((READ | WRITE) as u32) << DIRSHIFT;
#[doc(hidden)]
pub const SIZE_MASK: u32 = SIZEMASK << SIZESHIFT;