Skip to content

Commit

Permalink
Add ioctl support for BSD
Browse files Browse the repository at this point in the history
  • Loading branch information
Conrad Kramer committed Dec 10, 2016
1 parent cfcd249 commit bfb9150
Show file tree
Hide file tree
Showing 12 changed files with 206 additions and 136 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]

### Added
- Added support for `ioctl` calls on BSD platforms
([#478](https://github.com/nix-rust/nix/pull/478))
- Added struct `TimeSpec`
([#475](https://github.com/nix-rust/nix/pull/475))
- Added complete definitions for all kqueue-related constants on all supported
Expand All @@ -24,6 +26,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#457](https://github.com/nix-rust/nix/pull/457))

### Changed
- Removed the `bad` keyword from the `ioctl!` macro
([#478](https://github.com/nix-rust/nix/pull/478))
- Changed `TimeVal` into an opaque Newtype
([#475](https://github.com/nix-rust/nix/pull/475))
- `kill`'s signature, defined in `::nix::sys::signal`, changed, so that the
Expand Down
105 changes: 78 additions & 27 deletions src/sys/ioctl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,33 +104,13 @@
#[macro_use]
mod platform;

#[cfg(target_os = "macos")]
#[path = "platform/macos.rs"]
#[macro_use]
mod platform;

#[cfg(target_os = "ios")]
#[path = "platform/ios.rs"]
#[macro_use]
mod platform;

#[cfg(target_os = "freebsd")]
#[path = "platform/freebsd.rs"]
#[macro_use]
mod platform;

#[cfg(target_os = "netbsd")]
#[path = "platform/netbsd.rs"]
#[macro_use]
mod platform;

#[cfg(target_os = "openbsd")]
#[path = "platform/openbsd.rs"]
#[macro_use]
mod platform;

#[cfg(target_os = "dragonfly")]
#[path = "platform/dragonfly.rs"]
#[cfg(any(target_os = "macos",
target_os = "ios",
target_os = "netbsd",
target_os = "openbsd",
target_os = "freebsd",
target_os = "dragonfly"))]
#[path = "platform/bsd.rs"]
#[macro_use]
mod platform;

Expand All @@ -145,3 +125,74 @@ extern "C" {
/// A hack to get the macros to work nicely.
#[doc(hidden)]
pub use ::libc as libc;

/// Convert raw ioctl return value to a Nix result
#[macro_export]
macro_rules! convert_ioctl_res {
($w:expr) => (
{
$crate::Errno::result($w)
}
);
}

#[macro_export]
macro_rules! ioctl {
($name:ident with $nr:expr) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
data: *mut u8)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, $nr as $crate::sys::ioctl::libc::c_ulong, data))
}
);
(none $name:ident with $ioty:expr, $nr:expr) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, io!($ioty, $nr) as $crate::sys::ioctl::libc::c_ulong))
}
);
(read $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *mut $ty)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
(write $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *const $ty)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, iow!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
(readwrite $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *mut $ty)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, iorw!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
(read buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *mut $ty,
len: usize)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
(write buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *const $ty,
len: usize) -> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, iow!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
(readwrite buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *mut $ty,
len: usize)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, iorw!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
}
36 changes: 36 additions & 0 deletions src/sys/ioctl/platform/bsd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
mod consts {
pub const VOID: u32 = 0x20000000;
pub const OUT: u32 = 0x40000000;
pub const IN: u32 = 0x80000000;
pub const INOUT: u32 = (IN|OUT);
pub const IOCPARM_MASK: u32 = 0x1fff;
}

pub use self::consts::*;

#[macro_export]
macro_rules! ioc {
($inout:expr, $group:expr, $num:expr, $len:expr) => (
$inout | (($len as u32 & $crate::sys::ioctl::IOCPARM_MASK) << 16) | (($group as u32) << 8) | ($num as u32)
)
}

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

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

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

#[macro_export]
macro_rules! iorw {
($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::INOUT, $g, $n, $len))
}
Empty file.
Empty file removed src/sys/ioctl/platform/freebsd.rs
Empty file.
Empty file removed src/sys/ioctl/platform/ios.rs
Empty file.
72 changes: 0 additions & 72 deletions src/sys/ioctl/platform/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,78 +77,6 @@ macro_rules! iorw {
($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, $ty, $nr, $sz))
}

/// Convert raw ioctl return value to a Nix result
#[macro_export]
macro_rules! convert_ioctl_res {
($w:expr) => (
{
$crate::Errno::result($w)
}
);
}

/// Declare a wrapper function around an ioctl.
#[macro_export]
macro_rules! ioctl {
(bad $name:ident with $nr:expr) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
data: *mut u8)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, $nr as $crate::sys::ioctl::libc::c_ulong, data))
}
);
(none $name:ident with $ioty:expr, $nr:expr) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, io!($ioty, $nr) as $crate::sys::ioctl::libc::c_ulong))
}
);
(read $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *mut $ty)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
(write $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *const $ty)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, iow!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
(readwrite $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *mut $ty)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, iorw!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
(read buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *mut $ty,
len: usize)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
(write buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *const $ty,
len: usize) -> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, iow!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
(readwrite buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int,
val: *mut $ty,
len: usize)
-> $crate::Result<$crate::sys::ioctl::libc::c_int> {
convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, iorw!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val))
}
);
}

/// Extracts the "direction" (read/write/none) from an encoded ioctl command.
#[inline(always)]
pub fn ioc_dir(nr: u32) -> u8 {
Expand Down
Empty file removed src/sys/ioctl/platform/macos.rs
Empty file.
Empty file removed src/sys/ioctl/platform/netbsd.rs
Empty file.
Empty file removed src/sys/ioctl/platform/openbsd.rs
Empty file.
2 changes: 1 addition & 1 deletion src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod eventfd;
#[cfg(target_os = "linux")]
pub mod memfd;

#[cfg(not(any(target_os = "ios", target_os = "freebsd", target_os = "dragonfly")))]
#[macro_use]
pub mod ioctl;

#[cfg(any(target_os = "linux", target_os = "android"))]
Expand Down
Loading

0 comments on commit bfb9150

Please sign in to comment.