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