Skip to content

Commit

Permalink
Refactor the ioctl API and documentation
Browse files Browse the repository at this point in the history
 * Split `ioctl!` into separate macros. This makes documentation easier to read.
 * For every `ioctl_*!` macro include a description of the macro arguments as, the
   function prototype for the generated wrapper function, and an example if we have one.
 * Expose `request_code_*!` in the documentation to make the `ioctl_*_bad` macros easier to use.
 * Reorganize the file hierarchy to be simpler
  • Loading branch information
Bryant Mairs committed Jan 29, 2018
1 parent 2f09d4c commit 02e8367
Show file tree
Hide file tree
Showing 6 changed files with 619 additions and 252 deletions.
10 changes: 5 additions & 5 deletions src/sys/ioctl/platform/bsd.rs → src/sys/ioctl/bsd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pub type ioctl_num_type = ::libc::c_ulong;

mod consts {
use ::sys::ioctl::platform::ioctl_num_type;
use ::sys::ioctl::ioctl_num_type;
#[doc(hidden)]
pub const VOID: ioctl_num_type = 0x2000_0000;
#[doc(hidden)]
Expand All @@ -28,24 +28,24 @@ macro_rules! ioc {

#[macro_export]
#[doc(hidden)]
macro_rules! io {
macro_rules! request_code_none {
($g:expr, $n:expr) => (ioc!($crate::sys::ioctl::VOID, $g, $n, 0))
}

#[macro_export]
#[doc(hidden)]
macro_rules! ior {
macro_rules! request_code_read {
($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::OUT, $g, $n, $len))
}

#[macro_export]
#[doc(hidden)]
macro_rules! iow {
macro_rules! request_code_write {
($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::IN, $g, $n, $len))
}

#[macro_export]
#[doc(hidden)]
macro_rules! iorw {
macro_rules! request_code_readwrite {
($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::INOUT, $g, $n, $len))
}
68 changes: 45 additions & 23 deletions src/sys/ioctl/platform/linux.rs → src/sys/ioctl/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,6 @@ mod consts {
pub const DIRBITS: u8 = 3;
}

#[cfg(not(any(target_arch = "powerpc",
target_arch = "mips",
target_arch = "mips64",
target_arch = "x86",
target_arch = "arm",
target_arch = "x86_64",
target_arch = "powerpc64",
target_arch = "s390x",
target_arch = "aarch64")))]
use this_arch_not_supported;

// "Generic" ioctl protocol
#[cfg(any(target_arch = "x86",
target_arch = "arm",
Expand Down Expand Up @@ -86,30 +75,63 @@ macro_rules! ioc {
(($sz as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::SIZEMASK) << $crate::sys::ioctl::SIZESHIFT))
}

/// Encode an ioctl command that has no associated data.
/// 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]
#[doc(hidden)]
macro_rules! io {
macro_rules! request_code_none {
($ty:expr, $nr:expr) => (ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0))
}

/// Encode an ioctl command that reads.
/// 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]
#[doc(hidden)]
macro_rules! ior {
macro_rules! request_code_read {
($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz))
}

/// Encode an ioctl command that writes.
/// 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]
#[doc(hidden)]
macro_rules! iow {
macro_rules! request_code_write {
($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz))
}

/// Encode an ioctl command that both reads and writes.
/// 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]
#[doc(hidden)]
macro_rules! iorw {
macro_rules! request_code_readwrite {
($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, $ty, $nr, $sz))
}
Loading

0 comments on commit 02e8367

Please sign in to comment.