|
87 | 87 | //!
|
88 | 88 | //! More examples on using `ioctl!` can be found in the [rust-spidev crate](https://github.com/rust-embedded/rust-spidev).
|
89 | 89 | //!
|
90 |
| -//! ```text |
91 |
| -//! pub unsafe fn $NAME(fd: c_int, val: *mut u8, len: usize) -> Result<c_int>; |
92 |
| -//! ``` |
| 90 | +//! Using hard-coded ioctl numbers |
| 91 | +//! ------------------------------ |
93 | 92 | //!
|
94 | 93 | //! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of
|
95 | 94 | //! generating `ioctl` numbers and instead use hardcoded values. These can be used with the `bad`
|
96 | 95 | //! form of the `ioctl!` macro (there is no data transfer direction used with `bad`). The naming of
|
97 |
| -//! this comes from the Linux kernel which refers to these `ioctl`s as "bad". |
| 96 | +//! this comes from the Linux kernel which refers to these `ioctl`s as "bad". These are a different |
| 97 | +//! form as they bypass calling the macro that generates that ioctl number and instead use the |
| 98 | +//! defined value directly. These are supported by the `bad` prefix with the `ioctl!` macro. |
98 | 99 | //!
|
99 | 100 | //! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor.
|
100 | 101 | //! It can be implemented as:
|
|
104 | 105 | //! # #[cfg(any(target_os = "android", target_os = "linux"))]
|
105 | 106 | //! # use nix::libc::TCGETS as TCGETS;
|
106 | 107 | //! # #[cfg(any(target_os = "android", target_os = "linux"))]
|
107 |
| -//! ioctl!(bad tcgets with TCGETS); |
| 108 | +//! # use nix::libc::termios as termios; |
| 109 | +//! # #[cfg(any(target_os = "android", target_os = "linux"))] |
| 110 | +//! ioctl!(bad read tcgets with TCGETS; termios); |
108 | 111 | //! # fn main() {}
|
109 | 112 | //! ```
|
110 | 113 | //!
|
111 | 114 | //! The generated function has the same form as that generated by `read`:
|
112 | 115 | //!
|
113 | 116 | //! ```text
|
114 |
| -//! pub unsafe fn tcgets(fd: c_int, val: *mut u8) -> Result<c_int>; |
| 117 | +//! pub unsafe fn tcgets(fd: c_int, val: *mut termios) -> Result<c_int>; |
115 | 118 | //! ```
|
116 | 119 | //!
|
117 |
| -//! There is also a `bad none` form for use with hard-coded `ioctl`s that do not transfer data. |
118 |
| -//! The `TIOCEXCL` `ioctl` that's part of the termios API can be implemented as: |
| 120 | +//! There is also a `bad none`, `bad write`, and `bad readwrite` form that work similar to the |
| 121 | +//! standard `none`, `write`, and `readwrite` forms. |
119 | 122 | //!
|
120 | 123 | //! ```
|
121 | 124 | //! # #[macro_use] extern crate nix;
|
@@ -164,17 +167,31 @@ macro_rules! convert_ioctl_res {
|
164 | 167 | /// Generates ioctl functions. See [::sys::ioctl](sys/ioctl/index.html).
|
165 | 168 | #[macro_export]
|
166 | 169 | macro_rules! ioctl {
|
167 |
| - (bad $name:ident with $nr:expr) => ( |
| 170 | + (bad none $name:ident with $nr:expr) => ( |
| 171 | + pub unsafe fn $name(fd: $crate::libc::c_int) |
| 172 | + -> $crate::Result<$crate::libc::c_int> { |
| 173 | + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type)) |
| 174 | + } |
| 175 | + ); |
| 176 | + (bad read $name:ident with $nr:expr; $ty:ty) => ( |
168 | 177 | pub unsafe fn $name(fd: $crate::libc::c_int,
|
169 |
| - data: *mut u8) |
| 178 | + data: *mut $ty) |
170 | 179 | -> $crate::Result<$crate::libc::c_int> {
|
171 | 180 | convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
|
172 | 181 | }
|
173 | 182 | );
|
174 |
| - (bad none $name:ident with $nr:expr) => ( |
175 |
| - pub unsafe fn $name(fd: $crate::libc::c_int) |
| 183 | + (bad write $name:ident with $nr:expr; $ty:ty) => ( |
| 184 | + pub unsafe fn $name(fd: $crate::libc::c_int, |
| 185 | + data: &$ty) |
176 | 186 | -> $crate::Result<$crate::libc::c_int> {
|
177 |
| - convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type)) |
| 187 | + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) |
| 188 | + } |
| 189 | + ); |
| 190 | + (bad readwrite $name:ident with $nr:expr; $ty:ty) => ( |
| 191 | + pub unsafe fn $name(fd: $crate::libc::c_int, |
| 192 | + data: *mut $ty) |
| 193 | + -> $crate::Result<$crate::libc::c_int> { |
| 194 | + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) |
178 | 195 | }
|
179 | 196 | );
|
180 | 197 | (none $name:ident with $ioty:expr, $nr:expr) => (
|
|
0 commit comments