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