|
108 | 108 | //!
|
109 | 109 | //! More examples on using `ioctl!` can be found in the [rust-spidev crate](https://github.com/rust-embedded/rust-spidev).
|
110 | 110 | //!
|
111 |
| -//! ```text |
112 |
| -//! pub unsafe fn $NAME(fd: c_int, data: *mut u8, len: usize) -> Result<c_int>; |
113 |
| -//! ``` |
| 111 | +//! Using hard-coded ioctl numbers |
| 112 | +//! ------------------------------ |
114 | 113 | //!
|
115 | 114 | //! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of
|
116 |
| -//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the `bad` |
117 |
| -//! form of the `ioctl!` macro (there is no data transfer direction used with `bad`). The naming of |
118 |
| -//! this comes from the Linux kernel which refers to these `ioctl`s as "bad". |
| 115 | +//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the `bad *` |
| 116 | +//! variants of the `ioctl!` macro. This naming comes from the Linux kernel which refers to these |
| 117 | +//! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates |
| 118 | +//! the ioctl number and instead use the defined value directly. |
119 | 119 | //!
|
120 | 120 | //! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor.
|
121 |
| -//! It can be implemented as: |
| 121 | +//! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as: |
122 | 122 | //!
|
123 | 123 | //! ```
|
124 | 124 | //! # #[macro_use] extern crate nix;
|
125 | 125 | //! # #[cfg(any(target_os = "android", target_os = "linux"))]
|
126 | 126 | //! # use nix::libc::TCGETS as TCGETS;
|
127 | 127 | //! # #[cfg(any(target_os = "android", target_os = "linux"))]
|
128 |
| -//! ioctl!(bad tcgets with TCGETS); |
| 128 | +//! # use nix::libc::termios as termios; |
| 129 | +//! # #[cfg(any(target_os = "android", target_os = "linux"))] |
| 130 | +//! ioctl!(bad read tcgets with TCGETS; termios); |
129 | 131 | //! # fn main() {}
|
130 | 132 | //! ```
|
131 | 133 | //!
|
132 | 134 | //! The generated function has the same form as that generated by `read`:
|
133 | 135 | //!
|
134 | 136 | //! ```text
|
135 |
| -//! pub unsafe fn tcgets(fd: c_int, data: *mut u8) -> Result<c_int>; |
| 137 | +//! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result<c_int>; |
136 | 138 | //! ```
|
137 | 139 | //!
|
138 |
| -//! There is also a `bad none` form for use with hard-coded `ioctl`s that do not transfer data. |
139 |
| -//! The `TIOCEXCL` `ioctl` that's part of the termios API can be implemented as: |
| 140 | +//! There is also a `bad none`, `bad write_int`/`bad write_ptr`, and `bad readwrite` variant that work |
| 141 | +//! similar to the standard `none`, `write_int`/`write_ptr`, and `readwrite` variants. |
140 | 142 | //!
|
141 | 143 | //! ```
|
142 | 144 | //! # #[macro_use] extern crate nix;
|
@@ -185,17 +187,38 @@ macro_rules! convert_ioctl_res {
|
185 | 187 | /// Generates ioctl functions. See [::sys::ioctl](sys/ioctl/index.html).
|
186 | 188 | #[macro_export]
|
187 | 189 | macro_rules! ioctl {
|
188 |
| - (bad $name:ident with $nr:expr) => ( |
| 190 | + (bad none $name:ident with $nr:expr) => ( |
| 191 | + pub unsafe fn $name(fd: $crate::libc::c_int) |
| 192 | + -> $crate::Result<$crate::libc::c_int> { |
| 193 | + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type)) |
| 194 | + } |
| 195 | + ); |
| 196 | + (bad read $name:ident with $nr:expr; $ty:ty) => ( |
189 | 197 | pub unsafe fn $name(fd: $crate::libc::c_int,
|
190 |
| - data: *mut u8) |
| 198 | + data: *mut $ty) |
191 | 199 | -> $crate::Result<$crate::libc::c_int> {
|
192 | 200 | convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
|
193 | 201 | }
|
194 | 202 | );
|
195 |
| - (bad none $name:ident with $nr:expr) => ( |
196 |
| - pub unsafe fn $name(fd: $crate::libc::c_int) |
| 203 | + (bad write_ptr $name:ident with $nr:expr; $ty:ty) => ( |
| 204 | + pub unsafe fn $name(fd: $crate::libc::c_int, |
| 205 | + data: *const $ty) |
197 | 206 | -> $crate::Result<$crate::libc::c_int> {
|
198 |
| - convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type)) |
| 207 | + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) |
| 208 | + } |
| 209 | + ); |
| 210 | + (bad write_int $name:ident with $nr:expr) => ( |
| 211 | + pub unsafe fn $name(fd: $crate::libc::c_int, |
| 212 | + data: $crate::libc::c_int) |
| 213 | + -> $crate::Result<$crate::libc::c_int> { |
| 214 | + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) |
| 215 | + } |
| 216 | + ); |
| 217 | + (bad readwrite $name:ident with $nr:expr; $ty:ty) => ( |
| 218 | + pub unsafe fn $name(fd: $crate::libc::c_int, |
| 219 | + data: *mut $ty) |
| 220 | + -> $crate::Result<$crate::libc::c_int> { |
| 221 | + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) |
199 | 222 | }
|
200 | 223 | );
|
201 | 224 | (none $name:ident with $ioty:expr, $nr:expr) => (
|
|
0 commit comments