nix/sys/ioctl/mod.rs
1//! Provide helpers for making ioctl system calls.
2//!
3//! This library is pretty low-level and messy. `ioctl` is not fun.
4//!
5//! What is an `ioctl`?
6//! ===================
7//!
8//! The `ioctl` syscall is the grab-bag syscall on POSIX systems. Don't want to add a new
9//! syscall? Make it an `ioctl`! `ioctl` refers to both the syscall, and the commands that can be
10//! sent with it. `ioctl` stands for "IO control", and the commands are always sent to a file
11//! descriptor.
12//!
13//! It is common to see `ioctl`s used for the following purposes:
14//!
15//! * Provide read/write access to out-of-band data related to a device such as configuration
16//! (for instance, setting serial port options)
17//! * Provide a mechanism for performing full-duplex data transfers (for instance, xfer on SPI
18//! devices).
19//! * Provide access to control functions on a device (for example, on Linux you can send
20//! commands like pause, resume, and eject to the CDROM device.
21//! * Do whatever else the device driver creator thought made most sense.
22//!
23//! `ioctl`s are synchronous system calls and are similar to read and write calls in that regard.
24//! They operate on file descriptors and have an identifier that specifies what the ioctl is.
25//! Additionally they may read or write data and therefore need to pass along a data pointer.
26//! Besides the semantics of the ioctls being confusing, the generation of this identifer can also
27//! be difficult.
28//!
29//! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some
30//! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into
31//! subcomponents (For linux this is documented in
32//! [`Documentation/ioctl/ioctl-number.rst`](https://elixir.bootlin.com/linux/latest/source/Documentation/userspace-api/ioctl/ioctl-number.rst)):
33//!
34//! * Number: The actual ioctl ID
35//! * Type: A grouping of ioctls for a common purpose or driver
36//! * Size: The size in bytes of the data that will be transferred
37//! * Direction: Whether there is any data and if it's read, write, or both
38//!
39//! Newer drivers should not generate complete integer identifiers for their `ioctl`s instead
40//! preferring to use the 4 components above to generate the final ioctl identifier. Because of
41//! how old `ioctl`s are, however, there are many hard-coded `ioctl` identifiers. These are
42//! commonly referred to as "bad" in `ioctl` documentation.
43//!
44//! Defining `ioctl`s
45//! =================
46//!
47//! This library provides several `ioctl_*!` macros for binding `ioctl`s. These generate public
48//! unsafe functions that can then be used for calling the ioctl. This macro has a few different
49//! ways it can be used depending on the specific ioctl you're working with.
50//!
51//! A simple `ioctl` is `SPI_IOC_RD_MODE`. This ioctl works with the SPI interface on Linux. This
52//! specific `ioctl` reads the mode of the SPI device as a `u8`. It's declared in
53//! `/include/uapi/linux/spi/spidev.h` as `_IOR(SPI_IOC_MAGIC, 1, __u8)`. Since it uses the `_IOR`
54//! macro, we know it's a `read` ioctl and can use the `ioctl_read!` macro as follows:
55//!
56//! ```
57//! # #[macro_use] extern crate nix;
58//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
59//! const SPI_IOC_TYPE_MODE: u8 = 1;
60//! ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
61//! # fn main() {}
62//! ```
63//!
64//! This generates the function:
65//!
66//! ```
67//! # #[macro_use] extern crate nix;
68//! # use std::mem;
69//! # use nix::{libc, Result};
70//! # use nix::errno::Errno;
71//! # use nix::libc::c_int as c_int;
72//! # const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
73//! # const SPI_IOC_TYPE_MODE: u8 = 1;
74//! pub unsafe fn spi_read_mode(fd: c_int, data: *mut u8) -> Result<c_int> {
75//! let res = libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::<u8>()), data);
76//! Errno::result(res)
77//! }
78//! # fn main() {}
79//! ```
80//!
81//! The return value for the wrapper functions generated by the `ioctl_*!` macros are `nix::Error`s.
82//! These are generated by assuming the return value of the ioctl is `-1` on error and everything
83//! else is a valid return value. If this is not the case, `Result::map` can be used to map some
84//! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function.
85//!
86//! Writing `ioctl`s generally use pointers as their data source and these should use the
87//! `ioctl_write_ptr!`. But in some cases an `int` is passed directly. For these `ioctl`s use the
88//! `ioctl_write_int!` macro. This variant does not take a type as the last argument:
89//!
90//! ```
91//! # #[macro_use] extern crate nix;
92//! const HCI_IOC_MAGIC: u8 = b'k';
93//! const HCI_IOC_HCIDEVUP: u8 = 1;
94//! ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
95//! # fn main() {}
96//! ```
97//!
98//! Some `ioctl`s don't transfer any data, and those should use `ioctl_none!`. This macro
99//! doesn't take a type and so it is declared similar to the `write_int` variant shown above.
100//!
101//! The mode for a given `ioctl` should be clear from the documentation if it has good
102//! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl`
103//! number where `_IO`, `_IOR`, `_IOW`, and `_IOWR` map to "none", "read", "write_*", and "readwrite"
104//! respectively. To determine the specific `write_` variant to use you'll need to find
105//! what the argument type is supposed to be. If it's an `int`, then `write_int` should be used,
106//! otherwise it should be a pointer and `write_ptr` should be used. On Linux the
107//! [`ioctl_list` man page](https://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a
108//! large number of `ioctl`s and describes their argument data type.
109//!
110//! Using "bad" `ioctl`s
111//! --------------------
112//!
113//! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of
114//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the
115//! `ioctl_*_bad!` macros. This naming comes from the Linux kernel which refers to these
116//! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates
117//! the ioctl number and instead use the defined value directly.
118//!
119//! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor.
120//! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as:
121//!
122//! ```
123//! # #[macro_use] extern crate nix;
124//! # #[cfg(any(target_os = "android", target_os = "linux"))]
125//! # use nix::libc::TCGETS as TCGETS;
126//! # #[cfg(any(target_os = "android", target_os = "linux"))]
127//! # use nix::libc::termios as termios;
128//! # #[cfg(any(target_os = "android", target_os = "linux"))]
129//! ioctl_read_bad!(tcgets, TCGETS, termios);
130//! # fn main() {}
131//! ```
132//!
133//! The generated function has the same form as that generated by `ioctl_read!`:
134//!
135//! ```text
136//! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result<c_int>;
137//! ```
138//!
139//! Working with Arrays
140//! -------------------
141//!
142//! Some `ioctl`s work with entire arrays of elements. These are supported by the `ioctl_*_buf`
143//! family of macros: `ioctl_read_buf`, `ioctl_write_buf`, and `ioctl_readwrite_buf`. Note that
144//! there are no "bad" versions for working with buffers. The generated functions include a `len`
145//! argument to specify the number of elements (where the type of each element is specified in the
146//! macro).
147//!
148//! Again looking to the SPI `ioctl`s on Linux for an example, there is a `SPI_IOC_MESSAGE` `ioctl`
149//! that queues up multiple SPI messages by writing an entire array of `spi_ioc_transfer` structs.
150//! `linux/spi/spidev.h` defines a macro to calculate the `ioctl` number like:
151//!
152//! ```C
153//! #define SPI_IOC_MAGIC 'k'
154//! #define SPI_MSGSIZE(N) ...
155//! #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
156//! ```
157//!
158//! The `SPI_MSGSIZE(N)` calculation is already handled by the `ioctl_*!` macros, so all that's
159//! needed to define this `ioctl` is:
160//!
161//! ```
162//! # #[macro_use] extern crate nix;
163//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
164//! const SPI_IOC_TYPE_MESSAGE: u8 = 0;
165//! # pub struct spi_ioc_transfer(u64);
166//! ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
167//! # fn main() {}
168//! ```
169//!
170//! This generates a function like:
171//!
172//! ```
173//! # #[macro_use] extern crate nix;
174//! # use std::mem;
175//! # use nix::{libc, Result};
176//! # use nix::errno::Errno;
177//! # use nix::libc::c_int as c_int;
178//! # const SPI_IOC_MAGIC: u8 = b'k';
179//! # const SPI_IOC_TYPE_MESSAGE: u8 = 0;
180//! # pub struct spi_ioc_transfer(u64);
181//! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result<c_int> {
182//! let res = libc::ioctl(fd,
183//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()),
184//! data);
185//! Errno::result(res)
186//! }
187//! # fn main() {}
188//! ```
189//!
190//! Finding `ioctl` Documentation
191//! -----------------------------
192//!
193//! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot
194//! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are
195//! documented directly in the headers defining their constants, but others have more extensive
196//! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`).
197//!
198//! Documenting the Generated Functions
199//! ===================================
200//!
201//! In many cases, users will wish for the functions generated by the `ioctl`
202//! macro to be public and documented. For this reason, the generated functions
203//! are public by default. If you wish to hide the ioctl, you will need to put
204//! them in a private module.
205//!
206//! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an
207//! example :
208//!
209//! ```
210//! # #[macro_use] extern crate nix;
211//! # use nix::libc::c_int;
212//! ioctl_read! {
213//! /// Make the given terminal the controlling terminal of the calling process. The calling
214//! /// process must be a session leader and not have a controlling terminal already. If the
215//! /// terminal is already the controlling terminal of a different session group then the
216//! /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the
217//! /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen
218//! /// and all processes that had it as controlling terminal lose it.
219//! tiocsctty, b't', 19, c_int
220//! }
221//!
222//! # fn main() {}
223//! ```
224use cfg_if::cfg_if;
225
226#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
227#[macro_use]
228mod linux;
229
230#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
231pub use self::linux::*;
232
233#[cfg(any(target_os = "dragonfly",
234 target_os = "freebsd",
235 target_os = "illumos",
236 target_os = "ios",
237 target_os = "macos",
238 target_os = "netbsd",
239 target_os = "openbsd"))]
240#[macro_use]
241mod bsd;
242
243#[cfg(any(target_os = "dragonfly",
244 target_os = "freebsd",
245 target_os = "illumos",
246 target_os = "ios",
247 target_os = "macos",
248 target_os = "netbsd",
249 target_os = "openbsd"))]
250pub use self::bsd::*;
251
252/// Convert raw ioctl return value to a Nix result
253#[macro_export]
254#[doc(hidden)]
255macro_rules! convert_ioctl_res {
256 ($w:expr) => (
257 {
258 $crate::errno::Errno::result($w)
259 }
260 );
261}
262
263/// Generates a wrapper function for an ioctl that passes no data to the kernel.
264///
265/// The arguments to this macro are:
266///
267/// * The function name
268/// * The ioctl identifier
269/// * The ioctl sequence number
270///
271/// The generated function has the following signature:
272///
273/// ```rust,ignore
274/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
275/// ```
276///
277/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
278///
279/// # Example
280///
281/// The `videodev2` driver on Linux defines the `log_status` `ioctl` as:
282///
283/// ```C
284/// #define VIDIOC_LOG_STATUS _IO('V', 70)
285/// ```
286///
287/// This can be implemented in Rust like:
288///
289/// ```no_run
290/// # #[macro_use] extern crate nix;
291/// ioctl_none!(log_status, b'V', 70);
292/// fn main() {}
293/// ```
294#[macro_export(local_inner_macros)]
295macro_rules! ioctl_none {
296 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
297 $(#[$attr])*
298 pub unsafe fn $name(fd: $crate::libc::c_int)
299 -> $crate::Result<$crate::libc::c_int> {
300 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type))
301 }
302 )
303}
304
305/// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel.
306///
307/// The arguments to this macro are:
308///
309/// * The function name
310/// * The ioctl request code
311///
312/// The generated function has the following signature:
313///
314/// ```rust,ignore
315/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
316/// ```
317///
318/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
319///
320/// # Example
321///
322/// ```no_run
323/// # #[macro_use] extern crate nix;
324/// # use libc::TIOCNXCL;
325/// # use std::fs::File;
326/// # use std::os::unix::io::AsRawFd;
327/// ioctl_none_bad!(tiocnxcl, TIOCNXCL);
328/// fn main() {
329/// let file = File::open("/dev/ttyUSB0").unwrap();
330/// unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap();
331/// }
332/// ```
333// TODO: add an example using request_code_*!()
334#[macro_export(local_inner_macros)]
335macro_rules! ioctl_none_bad {
336 ($(#[$attr:meta])* $name:ident, $nr:expr) => (
337 $(#[$attr])*
338 pub unsafe fn $name(fd: $crate::libc::c_int)
339 -> $crate::Result<$crate::libc::c_int> {
340 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
341 }
342 )
343}
344
345/// Generates a wrapper function for an ioctl that reads data from the kernel.
346///
347/// The arguments to this macro are:
348///
349/// * The function name
350/// * The ioctl identifier
351/// * The ioctl sequence number
352/// * The data type passed by this ioctl
353///
354/// The generated function has the following signature:
355///
356/// ```rust,ignore
357/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
358/// ```
359///
360/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
361///
362/// # Example
363///
364/// ```
365/// # #[macro_use] extern crate nix;
366/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
367/// const SPI_IOC_TYPE_MODE: u8 = 1;
368/// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
369/// # fn main() {}
370/// ```
371#[macro_export(local_inner_macros)]
372macro_rules! ioctl_read {
373 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
374 $(#[$attr])*
375 pub unsafe fn $name(fd: $crate::libc::c_int,
376 data: *mut $ty)
377 -> $crate::Result<$crate::libc::c_int> {
378 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
379 }
380 )
381}
382
383/// Generates a wrapper function for a "bad" ioctl that reads data from the kernel.
384///
385/// The arguments to this macro are:
386///
387/// * The function name
388/// * The ioctl request code
389/// * The data type passed by this ioctl
390///
391/// The generated function has the following signature:
392///
393/// ```rust,ignore
394/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
395/// ```
396///
397/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
398///
399/// # Example
400///
401/// ```
402/// # #[macro_use] extern crate nix;
403/// # #[cfg(any(target_os = "android", target_os = "linux"))]
404/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
405/// # fn main() {}
406/// ```
407#[macro_export(local_inner_macros)]
408macro_rules! ioctl_read_bad {
409 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
410 $(#[$attr])*
411 pub unsafe fn $name(fd: $crate::libc::c_int,
412 data: *mut $ty)
413 -> $crate::Result<$crate::libc::c_int> {
414 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
415 }
416 )
417}
418
419/// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel.
420///
421/// The arguments to this macro are:
422///
423/// * The function name
424/// * The ioctl identifier
425/// * The ioctl sequence number
426/// * The data type passed by this ioctl
427///
428/// The generated function has the following signature:
429///
430/// ```rust,ignore
431/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
432/// ```
433///
434/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
435///
436/// # Example
437///
438/// ```
439/// # #[macro_use] extern crate nix;
440/// # pub struct v4l2_audio {}
441/// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio);
442/// # fn main() {}
443/// ```
444#[macro_export(local_inner_macros)]
445macro_rules! ioctl_write_ptr {
446 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
447 $(#[$attr])*
448 pub unsafe fn $name(fd: $crate::libc::c_int,
449 data: *const $ty)
450 -> $crate::Result<$crate::libc::c_int> {
451 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
452 }
453 )
454}
455
456/// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel.
457///
458/// The arguments to this macro are:
459///
460/// * The function name
461/// * The ioctl request code
462/// * The data type passed by this ioctl
463///
464/// The generated function has the following signature:
465///
466/// ```rust,ignore
467/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
468/// ```
469///
470/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
471///
472/// # Example
473///
474/// ```
475/// # #[macro_use] extern crate nix;
476/// # #[cfg(any(target_os = "android", target_os = "linux"))]
477/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios);
478/// # fn main() {}
479/// ```
480#[macro_export(local_inner_macros)]
481macro_rules! ioctl_write_ptr_bad {
482 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
483 $(#[$attr])*
484 pub unsafe fn $name(fd: $crate::libc::c_int,
485 data: *const $ty)
486 -> $crate::Result<$crate::libc::c_int> {
487 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
488 }
489 )
490}
491
492cfg_if!{
493 if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] {
494 /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
495 ///
496 /// The arguments to this macro are:
497 ///
498 /// * The function name
499 /// * The ioctl identifier
500 /// * The ioctl sequence number
501 ///
502 /// The generated function has the following signature:
503 ///
504 /// ```rust,ignore
505 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
506 /// ```
507 ///
508 /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
509 /// * BSD - `libc::c_int`
510 /// * Linux - `libc::c_ulong`
511 ///
512 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
513 ///
514 /// # Example
515 ///
516 /// ```
517 /// # #[macro_use] extern crate nix;
518 /// ioctl_write_int!(vt_activate, b'v', 4);
519 /// # fn main() {}
520 /// ```
521 #[macro_export(local_inner_macros)]
522 macro_rules! ioctl_write_int {
523 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
524 $(#[$attr])*
525 pub unsafe fn $name(fd: $crate::libc::c_int,
526 data: $crate::sys::ioctl::ioctl_param_type)
527 -> $crate::Result<$crate::libc::c_int> {
528 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data))
529 }
530 )
531 }
532 } else {
533 /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
534 ///
535 /// The arguments to this macro are:
536 ///
537 /// * The function name
538 /// * The ioctl identifier
539 /// * The ioctl sequence number
540 ///
541 /// The generated function has the following signature:
542 ///
543 /// ```rust,ignore
544 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
545 /// ```
546 ///
547 /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
548 /// * BSD - `libc::c_int`
549 /// * Linux - `libc::c_ulong`
550 ///
551 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
552 ///
553 /// # Example
554 ///
555 /// ```
556 /// # #[macro_use] extern crate nix;
557 /// const HCI_IOC_MAGIC: u8 = b'k';
558 /// const HCI_IOC_HCIDEVUP: u8 = 1;
559 /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
560 /// # fn main() {}
561 /// ```
562 #[macro_export(local_inner_macros)]
563 macro_rules! ioctl_write_int {
564 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
565 $(#[$attr])*
566 pub unsafe fn $name(fd: $crate::libc::c_int,
567 data: $crate::sys::ioctl::ioctl_param_type)
568 -> $crate::Result<$crate::libc::c_int> {
569 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$crate::libc::c_int>()) as $crate::sys::ioctl::ioctl_num_type, data))
570 }
571 )
572 }
573 }
574}
575
576/// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel.
577///
578/// The arguments to this macro are:
579///
580/// * The function name
581/// * The ioctl request code
582///
583/// The generated function has the following signature:
584///
585/// ```rust,ignore
586/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int>
587/// ```
588///
589/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
590///
591/// # Examples
592///
593/// ```
594/// # #[macro_use] extern crate nix;
595/// # #[cfg(any(target_os = "android", target_os = "linux"))]
596/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK);
597/// # fn main() {}
598/// ```
599///
600/// ```rust
601/// # #[macro_use] extern crate nix;
602/// const KVMIO: u8 = 0xAE;
603/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
604/// # fn main() {}
605/// ```
606#[macro_export(local_inner_macros)]
607macro_rules! ioctl_write_int_bad {
608 ($(#[$attr:meta])* $name:ident, $nr:expr) => (
609 $(#[$attr])*
610 pub unsafe fn $name(fd: $crate::libc::c_int,
611 data: $crate::libc::c_int)
612 -> $crate::Result<$crate::libc::c_int> {
613 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
614 }
615 )
616}
617
618/// Generates a wrapper function for an ioctl that reads and writes data to the kernel.
619///
620/// The arguments to this macro are:
621///
622/// * The function name
623/// * The ioctl identifier
624/// * The ioctl sequence number
625/// * The data type passed by this ioctl
626///
627/// The generated function has the following signature:
628///
629/// ```rust,ignore
630/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
631/// ```
632///
633/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
634///
635/// # Example
636///
637/// ```
638/// # #[macro_use] extern crate nix;
639/// # pub struct v4l2_audio {}
640/// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
641/// # fn main() {}
642/// ```
643#[macro_export(local_inner_macros)]
644macro_rules! ioctl_readwrite {
645 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
646 $(#[$attr])*
647 pub unsafe fn $name(fd: $crate::libc::c_int,
648 data: *mut $ty)
649 -> $crate::Result<$crate::libc::c_int> {
650 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
651 }
652 )
653}
654
655/// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel.
656///
657/// The arguments to this macro are:
658///
659/// * The function name
660/// * The ioctl request code
661/// * The data type passed by this ioctl
662///
663/// The generated function has the following signature:
664///
665/// ```rust,ignore
666/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
667/// ```
668///
669/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
670// TODO: Find an example for ioctl_readwrite_bad
671#[macro_export(local_inner_macros)]
672macro_rules! ioctl_readwrite_bad {
673 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
674 $(#[$attr])*
675 pub unsafe fn $name(fd: $crate::libc::c_int,
676 data: *mut $ty)
677 -> $crate::Result<$crate::libc::c_int> {
678 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
679 }
680 )
681}
682
683/// Generates a wrapper function for an ioctl that reads an array of elements from the kernel.
684///
685/// The arguments to this macro are:
686///
687/// * The function name
688/// * The ioctl identifier
689/// * The ioctl sequence number
690/// * The data type passed by this ioctl
691///
692/// The generated function has the following signature:
693///
694/// ```rust,ignore
695/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
696/// ```
697///
698/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
699// TODO: Find an example for ioctl_read_buf
700#[macro_export(local_inner_macros)]
701macro_rules! ioctl_read_buf {
702 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
703 $(#[$attr])*
704 pub unsafe fn $name(fd: $crate::libc::c_int,
705 data: &mut [$ty])
706 -> $crate::Result<$crate::libc::c_int> {
707 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
708 }
709 )
710}
711
712/// Generates a wrapper function for an ioctl that writes an array of elements to the kernel.
713///
714/// The arguments to this macro are:
715///
716/// * The function name
717/// * The ioctl identifier
718/// * The ioctl sequence number
719/// * The data type passed by this ioctl
720///
721/// The generated function has the following signature:
722///
723/// ```rust,ignore
724/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int>
725/// ```
726///
727/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
728///
729/// # Examples
730///
731/// ```
732/// # #[macro_use] extern crate nix;
733/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
734/// const SPI_IOC_TYPE_MESSAGE: u8 = 0;
735/// # pub struct spi_ioc_transfer(u64);
736/// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
737/// # fn main() {}
738/// ```
739#[macro_export(local_inner_macros)]
740macro_rules! ioctl_write_buf {
741 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
742 $(#[$attr])*
743 pub unsafe fn $name(fd: $crate::libc::c_int,
744 data: &[$ty])
745 -> $crate::Result<$crate::libc::c_int> {
746 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
747 }
748 )
749}
750
751/// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel.
752///
753/// The arguments to this macro are:
754///
755/// * The function name
756/// * The ioctl identifier
757/// * The ioctl sequence number
758/// * The data type passed by this ioctl
759///
760/// The generated function has the following signature:
761///
762/// ```rust,ignore
763/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
764/// ```
765///
766/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
767// TODO: Find an example for readwrite_buf
768#[macro_export(local_inner_macros)]
769macro_rules! ioctl_readwrite_buf {
770 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
771 $(#[$attr])*
772 pub unsafe fn $name(fd: $crate::libc::c_int,
773 data: &mut [$ty])
774 -> $crate::Result<$crate::libc::c_int> {
775 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
776 }
777 )
778}