summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sys/ioctl/mod.rs55
-rw-r--r--test/sys/test_ioctl.rs7
2 files changed, 44 insertions, 18 deletions
diff --git a/src/sys/ioctl/mod.rs b/src/sys/ioctl/mod.rs
index 058fc60a..f54384e6 100644
--- a/src/sys/ioctl/mod.rs
+++ b/src/sys/ioctl/mod.rs
@@ -108,35 +108,37 @@
//!
//! More examples on using `ioctl!` can be found in the [rust-spidev crate](https://github.com/rust-embedded/rust-spidev).
//!
-//! ```text
-//! pub unsafe fn $NAME(fd: c_int, data: *mut u8, len: usize) -> Result<c_int>;
-//! ```
+//! Using hard-coded ioctl numbers
+//! ------------------------------
//!
//! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of
-//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the `bad`
-//! form of the `ioctl!` macro (there is no data transfer direction used with `bad`). The naming of
-//! this comes from the Linux kernel which refers to these `ioctl`s as "bad".
+//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the `bad *`
+//! variants of the `ioctl!` macro. This naming comes from the Linux kernel which refers to these
+//! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates
+//! the ioctl number and instead use the defined value directly.
//!
//! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor.
-//! It can be implemented as:
+//! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as:
//!
//! ```
//! # #[macro_use] extern crate nix;
//! # #[cfg(any(target_os = "android", target_os = "linux"))]
//! # use nix::libc::TCGETS as TCGETS;
//! # #[cfg(any(target_os = "android", target_os = "linux"))]
-//! ioctl!(bad tcgets with TCGETS);
+//! # use nix::libc::termios as termios;
+//! # #[cfg(any(target_os = "android", target_os = "linux"))]
+//! ioctl!(bad read tcgets with TCGETS; termios);
//! # fn main() {}
//! ```
//!
//! The generated function has the same form as that generated by `read`:
//!
//! ```text
-//! pub unsafe fn tcgets(fd: c_int, data: *mut u8) -> Result<c_int>;
+//! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result<c_int>;
//! ```
//!
-//! There is also a `bad none` form for use with hard-coded `ioctl`s that do not transfer data.
-//! The `TIOCEXCL` `ioctl` that's part of the termios API can be implemented as:
+//! There is also a `bad none`, `bad write_int`/`bad write_ptr`, and `bad readwrite` variant that work
+//! similar to the standard `none`, `write_int`/`write_ptr`, and `readwrite` variants.
//!
//! ```
//! # #[macro_use] extern crate nix;
@@ -185,17 +187,38 @@ macro_rules! convert_ioctl_res {
/// Generates ioctl functions. See [::sys::ioctl](sys/ioctl/index.html).
#[macro_export]
macro_rules! ioctl {
- (bad $name:ident with $nr:expr) => (
+ (bad none $name:ident with $nr:expr) => (
+ pub unsafe fn $name(fd: $crate::libc::c_int)
+ -> $crate::Result<$crate::libc::c_int> {
+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
+ }
+ );
+ (bad read $name:ident with $nr:expr; $ty:ty) => (
pub unsafe fn $name(fd: $crate::libc::c_int,
- data: *mut u8)
+ data: *mut $ty)
-> $crate::Result<$crate::libc::c_int> {
convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
}
);
- (bad none $name:ident with $nr:expr) => (
- pub unsafe fn $name(fd: $crate::libc::c_int)
+ (bad write_ptr $name:ident with $nr:expr; $ty:ty) => (
+ pub unsafe fn $name(fd: $crate::libc::c_int,
+ data: *const $ty)
-> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
+ }
+ );
+ (bad write_int $name:ident with $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, $nr as $crate::sys::ioctl::ioctl_num_type, data))
+ }
+ );
+ (bad readwrite $name:ident with $nr:expr; $ty:ty) => (
+ pub unsafe fn $name(fd: $crate::libc::c_int,
+ data: *mut $ty)
+ -> $crate::Result<$crate::libc::c_int> {
+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
}
);
(none $name:ident with $ioty:expr, $nr:expr) => (
diff --git a/test/sys/test_ioctl.rs b/test/sys/test_ioctl.rs
index 7f0018d3..18432266 100644
--- a/test/sys/test_ioctl.rs
+++ b/test/sys/test_ioctl.rs
@@ -1,8 +1,11 @@
#![allow(dead_code)]
// Simple tests to ensure macro generated fns compile
-ioctl!(bad do_bad with 0x1234);
-ioctl!(bad none do_bad_none with 0x1234);
+ioctl!(bad none do_bad with 0x1234);
+ioctl!(bad read do_bad_read with 0x1234; u16);
+ioctl!(bad write_int do_bad_write_int with 0x1234);
+ioctl!(bad write_ptr do_bad_write_ptr with 0x1234; u8);
+ioctl!(bad readwrite do_bad_readwrite with 0x1234; u32);
ioctl!(none do_none with 0, 0);
ioctl!(read read_test with 0, 0; u32);
ioctl!(write_int write_ptr_int with 0, 0);