summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sys/ioctl/mod.rs28
-rw-r--r--test/sys/test_ioctl.rs9
2 files changed, 32 insertions, 5 deletions
diff --git a/src/sys/ioctl/mod.rs b/src/sys/ioctl/mod.rs
index 43114a5c..058fc60a 100644
--- a/src/sys/ioctl/mod.rs
+++ b/src/sys/ioctl/mod.rs
@@ -80,7 +80,22 @@
//! The return value for `ioctl` functions generated by the `ioctl!` macro are `nix::Error`s.
//! These are generated by assuming the return value of the ioctl is `-1` on error and everything
//! else is a valid return value. If this is not the case, `Result::map` can be used to map some
-//! of the range of "good" values (-2..-Inf, 0..Inf) into a smaller range in a helper function.
+//! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function.
+//!
+//! Writing `ioctl`s generally use pointers as their data source and these should use the
+//! `write_ptr` variant. But in some cases an `int` is passed directly. For these `ioctl`s use the
+//! `write_int` variant of the `ioctl!` macro. This variant does not take a type as the last argument:
+//!
+//! ```
+//! # #[macro_use] extern crate nix;
+//! const HCI_IOC_MAGIC: u8 = b'k';
+//! const HCI_IOC_HCIDEVUP: u8 = 1;
+//! ioctl!(write_int hci_dev_up with HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
+//! # fn main() {}
+//! ```
+//!
+//! Some `ioctl`s don't transfer any data, and those should use the `none` variant. This variant
+//! doesn't take a type and so it is declared similar to the `write_int` variant shown above.
//!
//! The mode for a given `ioctl` should be clear from the documentation if it has good
//! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl`
@@ -196,13 +211,20 @@ macro_rules! ioctl {
convert_ioctl_res!($crate::libc::ioctl(fd, ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
}
);
- (write $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
+ (write_ptr $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::libc::c_int,
- data: $ty)
+ data: *const $ty)
-> $crate::Result<$crate::libc::c_int> {
convert_ioctl_res!($crate::libc::ioctl(fd, iow!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
}
);
+ (write_int $name:ident with $ioty:expr, $nr:expr) => (
+ pub unsafe fn $name(fd: $crate::libc::c_int,
+ data: $crate::libc::c_int)
+ -> $crate::Result<$crate::libc::c_int> {
+ convert_ioctl_res!($crate::libc::ioctl(fd, iow!($ioty, $nr, ::std::mem::size_of::<$crate::libc::c_int>()) as $crate::sys::ioctl::ioctl_num_type, data))
+ }
+ );
(readwrite $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::libc::c_int,
data: *mut $ty)
diff --git a/test/sys/test_ioctl.rs b/test/sys/test_ioctl.rs
index c0ae078a..7f0018d3 100644
--- a/test/sys/test_ioctl.rs
+++ b/test/sys/test_ioctl.rs
@@ -5,10 +5,15 @@ ioctl!(bad do_bad with 0x1234);
ioctl!(bad none do_bad_none 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);
+ioctl!(write_int write_ptr_int with 0, 0);
+ioctl!(write_ptr write_ptr_u8 with 0, 0; u8);
+ioctl!(write_ptr write_ptr_u32 with 0, 0; u32);
+ioctl!(write_ptr write_ptr_u64 with 0, 0; u64);
ioctl!(readwrite readwrite_test with 0, 0; u64);
ioctl!(read buf readbuf_test with 0, 0; u32);
-ioctl!(write buf writebuf_test with 0, 0; u32);
+ioctl!(write buf writebuf_test_u8 with 0, 0; u8);
+ioctl!(write buf writebuf_test_u32 with 0, 0; u32);
+ioctl!(write buf writebuf_test_u64 with 0, 0; u64);
ioctl!(readwrite buf readwritebuf_test with 0, 0; u32);
// See C code for source of values for op calculations (does NOT work for mips/powerpc):