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