summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConrad Kramer <conrad@kramerapps.com>2016-11-25 00:10:15 -0500
committerConrad Kramer <conrad@kramerapps.com>2016-12-10 12:26:23 -0800
commitbfb91506316a98500e0b1ed8a2a847831cf0cccb (patch)
tree0b5b817b3da90f122c785a4ba3916253b0cc9bee
parentcfcd249acd6b079534ee085e3469b0720e17e1c9 (diff)
downloadnix-bfb91506316a98500e0b1ed8a2a847831cf0cccb.zip
Add ioctl support for BSD
-rw-r--r--CHANGELOG.md4
-rw-r--r--src/sys/ioctl/mod.rs105
-rw-r--r--src/sys/ioctl/platform/bsd.rs36
-rw-r--r--src/sys/ioctl/platform/dragonfly.rs0
-rw-r--r--src/sys/ioctl/platform/freebsd.rs0
-rw-r--r--src/sys/ioctl/platform/ios.rs0
-rw-r--r--src/sys/ioctl/platform/linux.rs72
-rw-r--r--src/sys/ioctl/platform/macos.rs0
-rw-r--r--src/sys/ioctl/platform/netbsd.rs0
-rw-r--r--src/sys/ioctl/platform/openbsd.rs0
-rw-r--r--src/sys/mod.rs2
-rw-r--r--test/sys/test_ioctl.rs123
12 files changed, 206 insertions, 136 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6dd85e1c..232128da 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
@@ -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
diff --git a/src/sys/ioctl/mod.rs b/src/sys/ioctl/mod.rs
index 387024f4..a04e9d39 100644
--- a/src/sys/ioctl/mod.rs
+++ b/src/sys/ioctl/mod.rs
@@ -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;
@@ -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))
+ }
+ );
+}
diff --git a/src/sys/ioctl/platform/bsd.rs b/src/sys/ioctl/platform/bsd.rs
new file mode 100644
index 00000000..57b4d637
--- /dev/null
+++ b/src/sys/ioctl/platform/bsd.rs
@@ -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))
+}
diff --git a/src/sys/ioctl/platform/dragonfly.rs b/src/sys/ioctl/platform/dragonfly.rs
deleted file mode 100644
index e69de29b..00000000
--- a/src/sys/ioctl/platform/dragonfly.rs
+++ /dev/null
diff --git a/src/sys/ioctl/platform/freebsd.rs b/src/sys/ioctl/platform/freebsd.rs
deleted file mode 100644
index e69de29b..00000000
--- a/src/sys/ioctl/platform/freebsd.rs
+++ /dev/null
diff --git a/src/sys/ioctl/platform/ios.rs b/src/sys/ioctl/platform/ios.rs
deleted file mode 100644
index e69de29b..00000000
--- a/src/sys/ioctl/platform/ios.rs
+++ /dev/null
diff --git a/src/sys/ioctl/platform/linux.rs b/src/sys/ioctl/platform/linux.rs
index 3719fd0c..aacea459 100644
--- a/src/sys/ioctl/platform/linux.rs
+++ b/src/sys/ioctl/platform/linux.rs
@@ -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 {
diff --git a/src/sys/ioctl/platform/macos.rs b/src/sys/ioctl/platform/macos.rs
deleted file mode 100644
index e69de29b..00000000
--- a/src/sys/ioctl/platform/macos.rs
+++ /dev/null
diff --git a/src/sys/ioctl/platform/netbsd.rs b/src/sys/ioctl/platform/netbsd.rs
deleted file mode 100644
index e69de29b..00000000
--- a/src/sys/ioctl/platform/netbsd.rs
+++ /dev/null
diff --git a/src/sys/ioctl/platform/openbsd.rs b/src/sys/ioctl/platform/openbsd.rs
deleted file mode 100644
index e69de29b..00000000
--- a/src/sys/ioctl/platform/openbsd.rs
+++ /dev/null
diff --git a/src/sys/mod.rs b/src/sys/mod.rs
index 793bc70e..706614dc 100644
--- a/src/sys/mod.rs
+++ b/src/sys/mod.rs
@@ -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"))]
diff --git a/test/sys/test_ioctl.rs b/test/sys/test_ioctl.rs
index 94eca447..1d9fbcc8 100644
--- a/test/sys/test_ioctl.rs
+++ b/test/sys/test_ioctl.rs
@@ -1,9 +1,7 @@
#![allow(dead_code)]
-#![cfg(target_os = "linux")] // no ioctl support for osx yet
-
// Simple tests to ensure macro generated fns compile
-ioctl!(bad do_bad with 0x1234);
+ioctl!(do_bad with 0x1234);
ioctl!(none do_none with 0, 0);
ioctl!(read read_test with 0, 0; u32);
ioctl!(write write_test with 0, 0; u64);
@@ -15,44 +13,97 @@ ioctl!(readwrite buf readwritebuf_test with 0, 0; u32);
// See C code for source of values for op calculations:
// https://gist.github.com/posborne/83ea6880770a1aef332e
-#[test]
-fn test_op_none() {
- assert_eq!(io!(b'q', 10), 0x0000710A);
- assert_eq!(io!(b'a', 255), 0x000061FF);
-}
+#[cfg(any(target_os = "linux", target_os = "android"))]
+mod linux {
+ #[test]
+ fn test_op_none() {
+ assert_eq!(io!(b'q', 10), 0x0000710A);
+ assert_eq!(io!(b'a', 255), 0x000061FF);
+ }
-#[test]
-fn test_op_write() {
- assert_eq!(iow!(b'z', 10, 1), 0x40017A0A);
- assert_eq!(iow!(b'z', 10, 512), 0x42007A0A);
-}
+ #[test]
+ fn test_op_write() {
+ assert_eq!(iow!(b'z', 10, 1), 0x40017A0A);
+ assert_eq!(iow!(b'z', 10, 512), 0x42007A0A);
+ }
-#[cfg(target_pointer_width = "64")]
-#[test]
-fn test_op_write_64() {
- assert_eq!(iow!(b'z', 10, (1 as u64) << 32), 0x40007A0A);
-}
+ #[cfg(target_pointer_width = "64")]
+ #[test]
+ fn test_op_write_64() {
+ assert_eq!(iow!(b'z', 10, (1 as u64) << 32), 0x40007A0A);
+ }
-#[test]
-fn test_op_read() {
- assert_eq!(ior!(b'z', 10, 1), 0x80017A0A);
- assert_eq!(ior!(b'z', 10, 512), 0x82007A0A);
-}
+ #[test]
+ fn test_op_read() {
+ assert_eq!(ior!(b'z', 10, 1), 0x80017A0A);
+ assert_eq!(ior!(b'z', 10, 512), 0x82007A0A);
+ }
-#[cfg(target_pointer_width = "64")]
-#[test]
-fn test_op_read_64() {
- assert_eq!(ior!(b'z', 10, (1 as u64) << 32), 0x80007A0A);
-}
+ #[cfg(target_pointer_width = "64")]
+ #[test]
+ fn test_op_read_64() {
+ assert_eq!(ior!(b'z', 10, (1 as u64) << 32), 0x80007A0A);
+ }
+
+ #[test]
+ fn test_op_read_write() {
+ assert_eq!(iorw!(b'z', 10, 1), 0xC0017A0A);
+ assert_eq!(iorw!(b'z', 10, 512), 0xC2007A0A);
+ }
-#[test]
-fn test_op_read_write() {
- assert_eq!(iorw!(b'z', 10, 1), 0xC0017A0A);
- assert_eq!(iorw!(b'z', 10, 512), 0xC2007A0A);
+ #[cfg(target_pointer_width = "64")]
+ #[test]
+ fn test_op_read_write_64() {
+ assert_eq!(iorw!(b'z', 10, (1 as u64) << 32), 0xC0007A0A);
+ }
}
-#[cfg(target_pointer_width = "64")]
-#[test]
-fn test_op_read_write_64() {
- assert_eq!(iorw!(b'z', 10, (1 as u64) << 32), 0xC0007A0A);
+#[cfg(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "freebsd",
+ target_os = "dragonfly"))]
+mod bsd {
+ #[test]
+ fn test_op_none() {
+ assert_eq!(io!(b'q', 10), 0x2000710A);
+ assert_eq!(io!(b'a', 255), 0x200061FF);
+ }
+
+ #[test]
+ fn test_op_write() {
+ assert_eq!(iow!(b'z', 10, 1), 0x80017A0A);
+ assert_eq!(iow!(b'z', 10, 512), 0x82007A0A);
+ }
+
+ #[cfg(target_pointer_width = "64")]
+ #[test]
+ fn test_op_write_64() {
+ assert_eq!(iow!(b'z', 10, (1 as u64) << 32), 0x80007A0A);
+ }
+
+ #[test]
+ fn test_op_read() {
+ assert_eq!(ior!(b'z', 10, 1), 0x40017A0A);
+ assert_eq!(ior!(b'z', 10, 512), 0x42007A0A);
+ }
+
+ #[cfg(target_pointer_width = "64")]
+ #[test]
+ fn test_op_read_64() {
+ assert_eq!(ior!(b'z', 10, (1 as u64) << 32), 0x40007A0A);
+ }
+
+ #[test]
+ fn test_op_read_write() {
+ assert_eq!(iorw!(b'z', 10, 1), 0xC0017A0A);
+ assert_eq!(iorw!(b'z', 10, 512), 0xC2007A0A);
+ }
+
+ #[cfg(target_pointer_width = "64")]
+ #[test]
+ fn test_op_read_write_64() {
+ assert_eq!(iorw!(b'z', 10, (1 as u64) << 32), 0xC0007A0A);
+ }
}