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 = unsafe { 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(linux_android)]
125//! # use nix::libc::TCGETS as TCGETS;
126//! # #[cfg(linux_android)]
127//! # use nix::libc::termios as termios;
128//! # #[cfg(linux_android)]
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 = unsafe {
183//! libc::ioctl(
184//! fd,
185//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()),
186//! data
187//! )
188//! };
189//! Errno::result(res)
190//! }
191//! # fn main() {}
192//! ```
193//!
194//! Finding `ioctl` Documentation
195//! -----------------------------
196//!
197//! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot
198//! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are
199//! documented directly in the headers defining their constants, but others have more extensive
200//! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`).
201//!
202//! Documenting the Generated Functions
203//! ===================================
204//!
205//! In many cases, users will wish for the functions generated by the `ioctl`
206//! macro to be public and documented. For this reason, the generated functions
207//! are public by default. If you wish to hide the ioctl, you will need to put
208//! them in a private module.
209//!
210//! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an
211//! example :
212//!
213//! ```
214//! # #[macro_use] extern crate nix;
215//! # use nix::libc::c_int;
216//! ioctl_read! {
217//! /// Make the given terminal the controlling terminal of the calling process. The calling
218//! /// process must be a session leader and not have a controlling terminal already. If the
219//! /// terminal is already the controlling terminal of a different session group then the
220//! /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the
221//! /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen
222//! /// and all processes that had it as controlling terminal lose it.
223//! tiocsctty, b't', 19, c_int
224//! }
225//!
226//! # fn main() {}
227//! ```
228use cfg_if::cfg_if;
229
230#[cfg(any(
231 linux_android,
232 target_os = "fuchsia",
233 target_os = "redox",
234 target_os = "cygwin"
235))]
236#[macro_use]
237mod linux;
238
239#[cfg(any(
240 linux_android,
241 target_os = "fuchsia",
242 target_os = "redox",
243 target_os = "cygwin"
244))]
245pub use self::linux::*;
246
247#[cfg(any(bsd, solarish, target_os = "haiku",))]
248#[macro_use]
249mod bsd;
250
251#[cfg(any(bsd, solarish, target_os = "haiku",))]
252pub use self::bsd::*;
253
254/// Convert raw ioctl return value to a Nix result
255#[macro_export]
256#[doc(hidden)]
257macro_rules! convert_ioctl_res {
258 ($w:expr) => {{
259 $crate::errno::Errno::result($w)
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 unsafe {
301 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type))
302 }
303 }
304 )
305}
306
307/// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel.
308///
309/// The arguments to this macro are:
310///
311/// * The function name
312/// * The ioctl request code
313///
314/// The generated function has the following signature:
315///
316/// ```rust,ignore
317/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
318/// ```
319///
320/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
321///
322/// # Example
323///
324/// ```no_run
325/// # #[macro_use] extern crate nix;
326/// # use libc::TIOCNXCL;
327/// # use std::fs::File;
328/// # use std::os::unix::io::AsRawFd;
329/// ioctl_none_bad!(tiocnxcl, TIOCNXCL);
330/// fn main() {
331/// let file = File::open("/dev/ttyUSB0").unwrap();
332/// unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap();
333/// }
334/// ```
335// TODO: add an example using request_code_*!()
336#[macro_export(local_inner_macros)]
337macro_rules! ioctl_none_bad {
338 ($(#[$attr:meta])* $name:ident, $nr:expr) => (
339 $(#[$attr])*
340 pub unsafe fn $name(fd: $crate::libc::c_int)
341 -> $crate::Result<$crate::libc::c_int> {
342 unsafe {
343 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
344 }
345 }
346 )
347}
348
349/// Generates a wrapper function for an ioctl that reads data from the kernel.
350///
351/// The arguments to this macro are:
352///
353/// * The function name
354/// * The ioctl identifier
355/// * The ioctl sequence number
356/// * The data type passed by this ioctl
357///
358/// The generated function has the following signature:
359///
360/// ```rust,ignore
361/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
362/// ```
363///
364/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
365///
366/// # Example
367///
368/// ```
369/// # #[macro_use] extern crate nix;
370/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
371/// const SPI_IOC_TYPE_MODE: u8 = 1;
372/// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
373/// # fn main() {}
374/// ```
375#[macro_export(local_inner_macros)]
376macro_rules! ioctl_read {
377 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
378 $(#[$attr])*
379 pub unsafe fn $name(fd: $crate::libc::c_int,
380 data: *mut $ty)
381 -> $crate::Result<$crate::libc::c_int> {
382 unsafe {
383 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))
384 }
385 }
386 )
387}
388
389/// Generates a wrapper function for a "bad" ioctl that reads data from the kernel.
390///
391/// The arguments to this macro are:
392///
393/// * The function name
394/// * The ioctl request code
395/// * The data type passed by this ioctl
396///
397/// The generated function has the following signature:
398///
399/// ```rust,ignore
400/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
401/// ```
402///
403/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
404///
405/// # Example
406///
407/// ```
408/// # #[macro_use] extern crate nix;
409/// # #[cfg(linux_android)]
410/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
411/// # fn main() {}
412/// ```
413#[macro_export(local_inner_macros)]
414macro_rules! ioctl_read_bad {
415 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
416 $(#[$attr])*
417 pub unsafe fn $name(fd: $crate::libc::c_int,
418 data: *mut $ty)
419 -> $crate::Result<$crate::libc::c_int> {
420 unsafe {
421 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
422 }
423 }
424 )
425}
426
427/// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel.
428///
429/// The arguments to this macro are:
430///
431/// * The function name
432/// * The ioctl identifier
433/// * The ioctl sequence number
434/// * The data type passed by this ioctl
435///
436/// The generated function has the following signature:
437///
438/// ```rust,ignore
439/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
440/// ```
441///
442/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
443///
444/// # Example
445///
446/// ```
447/// # #[macro_use] extern crate nix;
448/// # pub struct v4l2_audio {}
449/// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio);
450/// # fn main() {}
451/// ```
452#[macro_export(local_inner_macros)]
453macro_rules! ioctl_write_ptr {
454 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
455 $(#[$attr])*
456 pub unsafe fn $name(fd: $crate::libc::c_int,
457 data: *const $ty)
458 -> $crate::Result<$crate::libc::c_int> {
459 unsafe {
460 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))
461 }
462 }
463 )
464}
465
466/// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel.
467///
468/// The arguments to this macro are:
469///
470/// * The function name
471/// * The ioctl request code
472/// * The data type passed by this ioctl
473///
474/// The generated function has the following signature:
475///
476/// ```rust,ignore
477/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
478/// ```
479///
480/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
481///
482/// # Example
483///
484/// ```
485/// # #[macro_use] extern crate nix;
486/// # #[cfg(linux_android)]
487/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios);
488/// # fn main() {}
489/// ```
490#[macro_export(local_inner_macros)]
491macro_rules! ioctl_write_ptr_bad {
492 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
493 $(#[$attr])*
494 pub unsafe fn $name(fd: $crate::libc::c_int,
495 data: *const $ty)
496 -> $crate::Result<$crate::libc::c_int> {
497 unsafe {
498 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
499 }
500 }
501 )
502}
503
504cfg_if! {
505 if #[cfg(freebsdlike)] {
506 /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
507 ///
508 /// The arguments to this macro are:
509 ///
510 /// * The function name
511 /// * The ioctl identifier
512 /// * The ioctl sequence number
513 ///
514 /// The generated function has the following signature:
515 ///
516 /// ```rust,ignore
517 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
518 /// ```
519 ///
520 /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
521 /// * BSD - `libc::c_int`
522 /// * Linux - `libc::c_ulong`
523 ///
524 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
525 ///
526 /// # Example
527 ///
528 /// ```
529 /// # #[macro_use] extern crate nix;
530 /// ioctl_write_int!(vt_activate, b'v', 4);
531 /// # fn main() {}
532 /// ```
533 #[macro_export(local_inner_macros)]
534 macro_rules! ioctl_write_int {
535 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
536 $(#[$attr])*
537 pub unsafe fn $name(fd: $crate::libc::c_int,
538 data: $crate::sys::ioctl::ioctl_param_type)
539 -> $crate::Result<$crate::libc::c_int> {
540 unsafe {
541 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data))
542 }
543 }
544 )
545 }
546 } else {
547 /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
548 ///
549 /// The arguments to this macro are:
550 ///
551 /// * The function name
552 /// * The ioctl identifier
553 /// * The ioctl sequence number
554 ///
555 /// The generated function has the following signature:
556 ///
557 /// ```rust,ignore
558 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
559 /// ```
560 ///
561 /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
562 /// * BSD - `libc::c_int`
563 /// * Linux - `libc::c_ulong`
564 ///
565 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
566 ///
567 /// # Example
568 ///
569 /// ```
570 /// # #[macro_use] extern crate nix;
571 /// const HCI_IOC_MAGIC: u8 = b'k';
572 /// const HCI_IOC_HCIDEVUP: u8 = 1;
573 /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
574 /// # fn main() {}
575 /// ```
576 #[macro_export(local_inner_macros)]
577 macro_rules! ioctl_write_int {
578 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
579 $(#[$attr])*
580 pub unsafe fn $name(fd: $crate::libc::c_int,
581 data: $crate::sys::ioctl::ioctl_param_type)
582 -> $crate::Result<$crate::libc::c_int> {
583 unsafe {
584 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))
585 }
586 }
587 )
588 }
589 }
590}
591
592/// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel.
593///
594/// The arguments to this macro are:
595///
596/// * The function name
597/// * The ioctl request code
598///
599/// The generated function has the following signature:
600///
601/// ```rust,ignore
602/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int>
603/// ```
604///
605/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
606///
607/// # Examples
608///
609/// ```
610/// # #[macro_use] extern crate nix;
611/// # #[cfg(linux_android)]
612/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK);
613/// # fn main() {}
614/// ```
615///
616/// ```rust
617/// # #[macro_use] extern crate nix;
618/// const KVMIO: u8 = 0xAE;
619/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
620/// # fn main() {}
621/// ```
622#[macro_export(local_inner_macros)]
623macro_rules! ioctl_write_int_bad {
624 ($(#[$attr:meta])* $name:ident, $nr:expr) => (
625 $(#[$attr])*
626 pub unsafe fn $name(fd: $crate::libc::c_int,
627 data: $crate::libc::c_int)
628 -> $crate::Result<$crate::libc::c_int> {
629 unsafe {
630 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
631 }
632 }
633 )
634}
635
636/// Generates a wrapper function for an ioctl that reads and writes data to the kernel.
637///
638/// The arguments to this macro are:
639///
640/// * The function name
641/// * The ioctl identifier
642/// * The ioctl sequence number
643/// * The data type passed by this ioctl
644///
645/// The generated function has the following signature:
646///
647/// ```rust,ignore
648/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
649/// ```
650///
651/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
652///
653/// # Example
654///
655/// ```
656/// # #[macro_use] extern crate nix;
657/// # pub struct v4l2_audio {}
658/// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
659/// # fn main() {}
660/// ```
661#[macro_export(local_inner_macros)]
662macro_rules! ioctl_readwrite {
663 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
664 $(#[$attr])*
665 pub unsafe fn $name(fd: $crate::libc::c_int,
666 data: *mut $ty)
667 -> $crate::Result<$crate::libc::c_int> {
668 let ioty = $ioty;
669 let nr = $nr;
670 unsafe {
671 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))
672 }
673 }
674 )
675}
676
677/// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel.
678///
679/// The arguments to this macro are:
680///
681/// * The function name
682/// * The ioctl request code
683/// * The data type passed by this ioctl
684///
685/// The generated function has the following signature:
686///
687/// ```rust,ignore
688/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
689/// ```
690///
691/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
692// TODO: Find an example for ioctl_readwrite_bad
693#[macro_export(local_inner_macros)]
694macro_rules! ioctl_readwrite_bad {
695 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
696 $(#[$attr])*
697 pub unsafe fn $name(fd: $crate::libc::c_int,
698 data: *mut $ty)
699 -> $crate::Result<$crate::libc::c_int> {
700 unsafe {
701 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
702 }
703 }
704 )
705}
706
707/// Generates a wrapper function for an ioctl that reads an array of elements from the kernel.
708///
709/// The arguments to this macro are:
710///
711/// * The function name
712/// * The ioctl identifier
713/// * The ioctl sequence number
714/// * The data type passed by this ioctl
715///
716/// The generated function has the following signature:
717///
718/// ```rust,ignore
719/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
720/// ```
721///
722/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
723// TODO: Find an example for ioctl_read_buf
724#[macro_export(local_inner_macros)]
725macro_rules! ioctl_read_buf {
726 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
727 $(#[$attr])*
728 pub unsafe fn $name(fd: $crate::libc::c_int,
729 data: &mut [$ty])
730 -> $crate::Result<$crate::libc::c_int> {
731 unsafe {
732 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_mut_ptr()))
733 }
734 }
735 )
736}
737
738/// Generates a wrapper function for an ioctl that writes an array of elements to the kernel.
739///
740/// The arguments to this macro are:
741///
742/// * The function name
743/// * The ioctl identifier
744/// * The ioctl sequence number
745/// * The data type passed by this ioctl
746///
747/// The generated function has the following signature:
748///
749/// ```rust,ignore
750/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int>
751/// ```
752///
753/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
754///
755/// # Examples
756///
757/// ```
758/// # #[macro_use] extern crate nix;
759/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
760/// const SPI_IOC_TYPE_MESSAGE: u8 = 0;
761/// # pub struct spi_ioc_transfer(u64);
762/// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
763/// # fn main() {}
764/// ```
765#[macro_export(local_inner_macros)]
766macro_rules! ioctl_write_buf {
767 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
768 $(#[$attr])*
769 pub unsafe fn $name(fd: $crate::libc::c_int,
770 data: &[$ty])
771 -> $crate::Result<$crate::libc::c_int> {
772 unsafe {
773 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_ptr()))
774 }
775 }
776 )
777}
778
779/// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel.
780///
781/// The arguments to this macro are:
782///
783/// * The function name
784/// * The ioctl identifier
785/// * The ioctl sequence number
786/// * The data type passed by this ioctl
787///
788/// The generated function has the following signature:
789///
790/// ```rust,ignore
791/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
792/// ```
793///
794/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
795// TODO: Find an example for readwrite_buf
796#[macro_export(local_inner_macros)]
797macro_rules! ioctl_readwrite_buf {
798 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
799 $(#[$attr])*
800 pub unsafe fn $name(fd: $crate::libc::c_int,
801 data: &mut [$ty])
802 -> $crate::Result<$crate::libc::c_int> {
803 unsafe {
804 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_mut_ptr()))
805 }
806 }
807 )
808}