|
124 | 124 | //! There is also a `bad none`, `bad write`, and `bad readwrite` form that work similar to the
|
125 | 125 | //! standard `none`, `write`, and `readwrite` forms.
|
126 | 126 | //!
|
| 127 | +//! Working with arrays |
| 128 | +//! -------------------- |
| 129 | +//! |
| 130 | +//! Some `ioctl`s work with entire arrays of elements. These are supported by the `buf` suffix in |
| 131 | +//! the `ioctl!` macro which can be used by specifying `read buf`, `write buf`, and |
| 132 | +//! `readwrite buf`. Note that there are no "bad" versions for working with buffers. The generated |
| 133 | +//! functions include a `len` argument to specify the number of elements (where the type of each |
| 134 | +//! element is specified in the macro). |
| 135 | +//! |
| 136 | +//! Again looking to the SPI `ioctl`s on Linux for an example, `SPI_IOC_NR_TRANSFER` is an `ioctl` |
| 137 | +//! that queues up multiple SPI messages, so it writes an entire array of `spi_ioc_transfer` |
| 138 | +//! structs. This can be implemented like: |
| 139 | +//! |
127 | 140 | //! ```
|
128 | 141 | //! # #[macro_use] extern crate nix;
|
129 |
| -//! # use nix::libc::TIOCEXCL as TIOCEXCL; |
130 |
| -//! ioctl!(bad none tiocexcl with TIOCEXCL); |
| 142 | +//! # const SPI_IOC_MAGIC: nix::libc::c_int = 'k' as nix::libc::c_int; |
| 143 | +//! # const SPI_IOC_NR_TRANSFER: u8 = 0; |
| 144 | +//! # pub struct spi_ioc_transfer { |
| 145 | +//! # field1: u64, |
| 146 | +//! # } |
| 147 | +//! ioctl!(write buf spi_transfer_buf with SPI_IOC_MAGIC, SPI_IOC_NR_TRANSFER; spi_ioc_transfer); |
131 | 148 | //! # fn main() {}
|
132 | 149 | //! ```
|
133 | 150 | //!
|
134 |
| -//! More examples on using `ioctl!` can be found in the [rust-spidev crate](https://github.com/rust-embedded/rust-spidev). |
| 151 | +//! This generates a function like: |
| 152 | +//! |
| 153 | +//! ``` |
| 154 | +//! # #[macro_use] extern crate nix; |
| 155 | +//! # use nix::libc::c_int as c_int; |
| 156 | +//! # use nix::libc::c_ulong as c_ulong; |
| 157 | +//! # use std::mem; |
| 158 | +//! # use nix::{Errno, libc, Result}; |
| 159 | +//! # const SPI_IOC_MAGIC: u8 = 'k' as u8; |
| 160 | +//! # const SPI_IOC_NR_TRANSFER: u8 = 0; |
| 161 | +//! # pub struct spi_ioc_transfer { |
| 162 | +//! # field1: u64, |
| 163 | +//! # } |
| 164 | +//! pub unsafe fn spi_transfer_buf(fd: c_int, data: *mut spi_ioc_transfer, len: usize) -> Result<c_int> { |
| 165 | +//! let res = libc::ioctl(fd, ior!(SPI_IOC_MAGIC, SPI_IOC_NR_TRANSFER, len * mem::size_of::<u8>()), data); |
| 166 | +//! Errno::result(res) |
| 167 | +//! } |
| 168 | +//! # fn main() {} |
| 169 | +//! ``` |
135 | 170 | //!
|
136 | 171 | //! Finding ioctl documentation
|
137 | 172 | //! ---------------------------
|
@@ -230,23 +265,23 @@ macro_rules! ioctl {
|
230 | 265 | data: *mut $ty,
|
231 | 266 | len: usize)
|
232 | 267 | -> $crate::Result<$crate::libc::c_int> {
|
233 |
| - convert_ioctl_res!($crate::libc::ioctl(fd, ior!($ioty, $nr, len) as $crate::sys::ioctl::ioctl_num_type, data)) |
| 268 | + convert_ioctl_res!($crate::libc::ioctl(fd, ior!($ioty, $nr, len * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) |
234 | 269 | }
|
235 | 270 | );
|
236 | 271 | (write buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
|
237 | 272 | pub unsafe fn $name(fd: $crate::libc::c_int,
|
238 | 273 | data: *const $ty,
|
239 | 274 | len: usize)
|
240 | 275 | -> $crate::Result<$crate::libc::c_int> {
|
241 |
| - convert_ioctl_res!($crate::libc::ioctl(fd, iow!($ioty, $nr, len) as $crate::sys::ioctl::ioctl_num_type, data)) |
| 276 | + convert_ioctl_res!($crate::libc::ioctl(fd, iow!($ioty, $nr, len * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) |
242 | 277 | }
|
243 | 278 | );
|
244 | 279 | (readwrite buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => (
|
245 | 280 | pub unsafe fn $name(fd: $crate::libc::c_int,
|
246 | 281 | data: *mut $ty,
|
247 | 282 | len: usize)
|
248 | 283 | -> $crate::Result<$crate::libc::c_int> {
|
249 |
| - convert_ioctl_res!($crate::libc::ioctl(fd, iorw!($ioty, $nr, len) as $crate::sys::ioctl::ioctl_num_type, data)) |
| 284 | + convert_ioctl_res!($crate::libc::ioctl(fd, iorw!($ioty, $nr, len * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) |
250 | 285 | }
|
251 | 286 | );
|
252 | 287 | }
|
0 commit comments